interface 和 extends 的使用冲突(附带接口和继承的复习)
1.当多个接口有相同方法签名,且在同一个实现类时
编译器会出现报错,如下:
class Pet implements Car,Animals{ // @Override // public void talk() { // Animals.super.talk(); // } } interface Animals{ default void talk(){ System.out.println("接口Animals-talk~~~~~~"); } } interface Car{ default void talk(){ System.out.println("接口Car-talk-------"); } }
一个实现类实现了多个接口,而多个接口中出现了方法签名相同的默认方法时:
A:保留其中一个:接口名.super.方法名
B:也可以完全重写
这里B方法就不赘述了,完全重写就ok
class Pet implements Car,Animals{ // 保留其中一个:接口名.super.方法名 @Override public void talk() { Animals.super.talk(); } } interface Animals{ default void talk(){ System.out.println("接口Animals-talk~~~~~~"); } } interface Car{ default void talk(){ System.out.println("接口Car-talk-------"); } }
完整代码:
package com.alex; /** * @Author Mr.Alex * @Date 2021/11/18 9:46 * @Version 1.0 */ public class Test01{ public static void main(String[] args) { Pet pet = new Pet(); pet.talk(); } } class Pet implements Car,Animals{ // 保留其中一个:接口名.super.方法名 @Override public void talk() { Animals.super.talk(); } } interface Animals{ default void talk(){ System.out.println("接口Animals-talk~~~~~~"); } } interface Car{ default void talk(){ System.out.println("接口Car-talk-------"); } }
2.当继承的父类和接口冲突时
一个实现类既继承父类,又实现接口,当父类中出现与接口的默认方法的方法签名相同的方法:
A:默认遵循亲爹原则,即保留父类的
B:也可以完全重写
package com.alex; /** * @Author Mr.Alex * @Date 2021/11/18 10:31 * @Version 1.0 */ public class Test02 { public static void main(String[] args) { Pets pets = new Pets(); pets.talk(); } } class Pets extends Animal implements Cars{ } class Animal{ public void talk(){ System.out.println("父类Animals-talk~~~~~~"); } } interface Cars{ public default void talk(){ System.out.println("接口Car-talk-------"); } }
复习:
1、公共的静态的常量:public static final
2、公共的抽象的方法:public abstract
非抽象的实现类必须重写
3、公共的默认方法:public default,JDK1.8之后
使用“实现类的对象."进行调用
实现类可以选择重写
4、公共的静态方法:public static, JDK1.8之后
只能使用”接口名.“进行调用
实现类不能重写
5、私有的方法:private(private不能省略)JDK1.9之后
final:最终的
1、修饰类:不能被继承
2、修饰方法:不能被重写
-
-
子类虽会继承父类私有(private)的成员,但子类不能对继承的私有成员直接进行访问,可通过继承的get/set方法进行访问。
结论:
(1)当父类的成员变量私有化时,在子类中是无法直接访问的,所以是否重名不影响,如果想要访问父类的私有成员变量,只能通过父类的get/set方法访问;
(2)当父类的成员变量非私有时,在子类中可以直接访问,所以如果有重名时,就需要加“super."进行区别。
1.@Override:写在方法上面,用来检测是不是有效的正确覆盖重写。这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。建议保留
2.必须保证父子类之间方法的名称相同,参数列表也相同。 3.子类方法的返回值类型必须【小于等于】父类方法的返回值类型(小于其实就是是它的子类,例如:Student < Person)。
注意:如果返回值类型是基本数据类型和void,那么必须是相同
4.子类方法的权限必须【大于等于】父类方法的权限修饰符。 小扩展提示:public > protected > 缺省 > private
5.几种特殊的方法不能被重写
-
静态方法不能被重写
-
私有等在子类中不可见的方法不能被重写
-
final方法不能被重写
-
所以子类是无法继承父类构造方法的。
-
构造方法的作用是初始化实例变量的,而子类又会从父类继承所有成员变量
所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个
super()
,表示调用父类的实例初始化方法,父类成员变量初始化后,才可以给子类使用。
结论:
子类对象实例化过程中必须先完成从父类继承的成员变量的实例初始化,这个过程是通过调用父类的实例初始化方法来完成的。
-
super():表示调用父类的无参实例初始化方法,要求父类必须有无参构造,而且可以省略不写;
-
super(实参列表):表示调用父类的有参实例初始化方法,当父类没有无参构造时,子类的构造器首行必须写super(实参列表)来明确调用父类的哪个有参构造(其实是调用该构造器对应的实例初始方法)
-
super()和super(实参列表)都只能出现在子类构造器的首行
外部类 | 成员变量 | 代码块 | 构造器 | 方法 | 局部变量 | |
---|---|---|---|---|---|---|
public | √ | √ | × | √ | √ | × |
protected | × | √ | × | √ | √ | × |
private | × | √ | × | √ | √ | × |
static | × | √ | √ | × | √ | × |
final | √ | √ | × | × | √ | √ |
abstract | √ | × | × | × | √ | × |
native | × | × | × | × | √ |
不能和abstract一起使用的修饰符?
(2)abstract和static不能一起修饰方法
(3)abstract和native不能一起修饰方法
(4)abstract和private不能一起修饰方法
static和final一起使用:
(1)修饰方法:可以,因为都不能被重写
(2)修饰成员变量:可以,表示静态常量
(3)修饰局部变量:不可以,static不能修饰局部变量
(4)修饰代码块:不可以,final不能修改代码块
(5)修饰内部类:可以一起修饰成员内部类,不能一起修饰局部内部类