从零开始学Java【21】

从零开始学Java【21】


​ 学习视频:https://www.bilibili.com/video/BV12J41137hu?p=74

抽象类

image-20220510092028592

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

image-20220510092557731

image-20220510092908491

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

如果子类不是抽象类,选择继承抽象类,那么就是重写它的方法:

image-20220510093209648

implement,选择方法:

image-20220510093257220

然后生成:

image-20220510093324239


抽象类本质上是一个类,而类就是要被继承的,Java中,继承extends只有单继承,所以extends是有局限性的,要是能有多继承就好了,此时可以引入一个概念:接口可以多继承。

另外,不能new这个抽象类,只能靠子类去实现它。如果需要new也只能new这个抽象类的子类。

image-20220510093823878

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

image-20220510094109201

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

image-20220510094231700

总结

  1. 抽象类和抽象方法其实就是一个约束,等待着具体的子类来对它进行实现。
  2. 不能new这个抽象类,只能靠子类去实现它。如果需要new也只能new这个抽象类的子类。
  3. 抽象类中能有抽象方法,也可以有普通方法。
  4. 抽象方法必须在抽象类中。
  5. extends单继承,而多继承概念接口可以实现。

思考

  1. 既然抽象类不能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()来调取抽象类的构造方法。

424acd1ce26142eda796d8beac8ed113

上图可以看到super(name)就是调取抽象类的构造器中的name属性。

  1. 抽象类存在的意义是什么?

比如打游戏,需要创建角色,而这个角色需要反复创建,就比较麻烦,可以把它的一些功能抽象出来,这样在创建角色的时候,只需要继承它的方法,然后自己去实现就可以了,相当于模板的作用。提高开发效率。

接口

image-20220510101523236

接口无法自己写方法。它只能做约束,即抽象的事情。

在以后编程中要实现约束与实现分离。

比如开始的时候把框架定义好,把接口全部设计好,文档定义好,然后找一些码农,把具体方法实现,即实现接口。

看完Java基础课之后,可以去看23种设计模式了。

接口有interface关键词

image-20220510104904276

image-20220510105033594

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

image-20220510105241431

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

image-20220510105611645

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

image-20220510110057844

如此就可以通过接口来实现多继承了。

同时接口内也可以定义常量

image-20220510111648648

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

image-20220510111720928

比较抽象类与接口

抽象类是abstract修饰的,是单继承的,后续子类用extends来单继承这个抽象类,实现这个类里面的方法。

接口是用interface修饰的,后续用一个implement修饰的类实现接口方法,并且这个类可以实现多个接口的方法,从而实现多继承。

总结

接口的作用:

  1. 约束
  2. 定义一些方法,让不同的人实现
  3. 接口中方法都是public abstract默认的,常量都是public static final默认的
  4. 接口不能实例化。因为接口没有构造方法
  5. implement可以实现多个接口,必须重写接口中的方法

内部类

image-20220510112025650

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

image-20220510113134869

通过实例化一个外部类的对象,然后用【外部对象.new】充当内部类的类型,这么对比:

外部:Outer outer = new Outer();,其中Outer是外部类的类型

内部:Outer.Inner inner = outer.new Inner();,其中outer.new是内部类的类型,而outer即是外部类的对象

  • 内部类可以调用内部类的方法,如上图及输出。
  • 内部类可以调用这个类的私有属性,这是比较便捷的地方

image-20220510114233200

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

  • 内部类可以调用外部类的公有/私有方法

image-20220510114927408

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

image-20220510115117988

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

image-20220510115531649

(图中出现其它错误先不用管)关于static在内部类这个问题,在以后学到多线程拉姆达表达式的时候会继续学习。

另外,一个Java类中可以有多个class类,但是只能有一个public class,所以内部类一般只写一个class即可,没有public修饰符。

小技巧:所以有时候想要写一个测试类,可以把测试类写到内部类里面,测试类是可以写main方法的,如下图:

image-20220510121455015

可以在内部进行测试

内部类参考文章:https://blog.csdn.net/weixin_46972127/article/details/123609366

里面降到了四种内部类的注意事项以及具体的操作

posted @ 2022-05-10 12:26  机智的小柴胡  阅读(57)  评论(0)    收藏  举报