从零开始学Java【21】
从零开始学Java【21】
学习视频:https://www.bilibili.com/video/BV12J41137hu?p=74
抽象类

在类声明的地方加上abstract就是抽象类了,写方法的时候,写个约束,具体到时候交给别人实现,也可以在方法声明加上abstract,变成抽象方法。


抽象类的所有方法,如果有类继承了这个抽象类,则必须实现这个抽象类的所有方法。除非这个子类也是个抽象类,那么子子类就需要实现,以此类推。也就是说,抽象类如果被继承,子类就需要实现它方法,除非子类也是抽象类。
如果子类不是抽象类,选择继承抽象类,那么就是重写它的方法:

implement,选择方法:

然后生成:

抽象类本质上是一个类,而类就是要被继承的,Java中,继承extends只有单继承,所以extends是有局限性的,要是能有多继承就好了,此时可以引入一个概念:接口可以多继承。
另外,不能new这个抽象类,只能靠子类去实现它。如果需要new也只能new这个抽象类的子类。

抽象类中能有抽象方法,也可以有普通方法。

但是,如果一个类有抽象方法,那么它必须是抽象类,可以看到,抽象方法必须在抽象类中

总结
- 抽象类和抽象方法其实就是一个约束,等待着具体的子类来对它进行实现。
- 不能new这个抽象类,只能靠子类去实现它。如果需要new也只能new这个抽象类的子类。
- 抽象类中能有抽象方法,也可以有普通方法。
- 抽象方法必须在抽象类中。
- extends单继承,而多继承概念接口可以实现。
思考
- 既然抽象类不能new对象,那抽象类是否存在构造器?
参考文章:https://blog.csdn.net/weixin_44544682/article/details/122549256
https://www.cnblogs.com/hyz051202020/p/14822069.html
https://blog.csdn.net/qq_44333770/article/details/120116793
抽象类中是存在构造器的。有提供子类用super()来调取抽象类的构造方法。

上图可以看到super(name)就是调取抽象类的构造器中的name属性。
- 抽象类存在的意义是什么?
比如打游戏,需要创建角色,而这个角色需要反复创建,就比较麻烦,可以把它的一些功能抽象出来,这样在创建角色的时候,只需要继承它的方法,然后自己去实现就可以了,相当于模板的作用。提高开发效率。
接口

接口无法自己写方法。它只能做约束,即抽象的事情。
在以后编程中要实现约束与实现分离。
比如开始的时候把框架定义好,把接口全部设计好,文档定义好,然后找一些码农,把具体方法实现,即实现接口。
看完Java基础课之后,可以去看23种设计模式了。
接口有interface关键词


可以看到,接口里面的方法中,public,abstract都是灰色的,那么意味着其实在接口里面这些关键词都是默认的。所以以后在接口里面写东西,可以省略public abstract,直接写类型+方法名字即可(以及形参)。

然后接口是需要实现的,用一个类来实现,加入关键字implement,来实现对应的接口,其中接口的方法可以进行重写,alt+insert重写方法即可,实现接口的类必须重写接口中的方法。

前面说了,extends是单继承,而接口可以多继承,如下图:一个类就可以实现两个接口的具体方法了:

如此就可以通过接口来实现多继承了。
同时接口内也可以定义常量

默认public static final作为前缀,去掉也可以

比较抽象类与接口
抽象类是abstract修饰的,是单继承的,后续子类用extends来单继承这个抽象类,实现这个类里面的方法。
接口是用interface修饰的,后续用一个implement修饰的类实现接口方法,并且这个类可以实现多个接口的方法,从而实现多继承。
总结
接口的作用:
- 约束
- 定义一些方法,让不同的人实现
- 接口中方法都是public abstract默认的,常量都是public static final默认的
- 接口不能实例化。因为接口没有构造方法
- implement可以实现多个接口,必须重写接口中的方法
内部类

在一个类中再定义一个类,即为内部类。

通过实例化一个外部类的对象,然后用【外部对象.new】充当内部类的类型,这么对比:
外部:Outer outer = new Outer();,其中Outer是外部类的类型
内部:Outer.Inner inner = outer.new Inner();,其中outer.new是内部类的类型,而outer即是外部类的对象
- 内部类可以调用内部类的方法,如上图及输出。
- 内部类可以调用这个类的私有属性,这是比较便捷的地方

请注意,这个方法是在内部类里面写的,则可以调用自身类的属性,非常方便。
- 内部类可以调用外部类的公有/私有方法

- 内部类可以被static修饰(static写在class前面)

可以看到,id报错,这是因为Inner内部类是静态的,随着类的加载而加载,调用id的时候这个id都还没被加载呢,这里可以链接之前的知识:静态可以调用静态,非静态可以调用静态,静态不可以调用非静态。要考虑他们加载的时间才行,所以这里要么把外部属性id也变成静态类,要么把内部类去掉静态修饰。

(图中出现其它错误先不用管)关于static在内部类这个问题,在以后学到多线程拉姆达表达式的时候会继续学习。
另外,一个Java类中可以有多个class类,但是只能有一个public class,所以内部类一般只写一个class即可,没有public修饰符。
小技巧:所以有时候想要写一个测试类,可以把测试类写到内部类里面,测试类是可以写main方法的,如下图:

可以在内部进行测试
内部类参考文章:https://blog.csdn.net/weixin_46972127/article/details/123609366
里面降到了四种内部类的注意事项以及具体的操作

浙公网安备 33010602011771号