继承
1259字约4分钟
2024-12-02
继承
继承说白了就是建立查找关系
继承的好处
- 代码的复用性提高了
- 代码的扩展性和维护性提高了
继承的注意事项
子类继承了父类的所有属性和方法,子类可以直接访问非私有的属性和方法,子类不能直接访问私有的属性和方法,要想访问私有的属性和方法则需要通过父类提供的公共的方法去访问
遇到无法调用的类时需要用公开的类来间接性调用
主方法(main方法)中不能直接调用父类中的属性和方法
如果子类所继承的父类不在同一个包下,则需要导包(
import
),把父类所在的 完整的包地址导包到自己的子类中总结:公开类无论在什么地方都可以被调用(在别的包中调用公开类要记得导入该类的包)
public class Test extends Demo01 { // 自定义方法 public void info() { // 使用父类中的属性 System.out.println("a = " + a + " b = " + b + " c = " + c); } // 主方法中不能直接使用父类的属性,只能通过对象调用 public static void main(String[] args) { // 创建Demo02对象 Demo02 demo02 = new Demo02(); // 调用demo02下的info方法 demo02.info(); } }
默认类只能在本包中使用,本包的子类可以直接调用默认类,别的包中的子类不能直接调用默认类
调用子类中的调用的属性时,会优先在子类中查找该属性,如果子类中没有则在父类中查找,如果父类中也没有,则继续在父类的父类中查找,直到找到为止,如果实在没有就会报错
在找的过程中如果找到了所对应的属性值,则会返回该值,并停止继续往下找,注意:尽管该值是一个私有的属性,也会停止,只要找到就停止,不管父类中有没有,但是找到私有的属性会报错
public class Test { public static void main(String[] args) { a a1 = new a(); System.out.println(a1.a1); // 输出 10 System.out.println(a1.a); // 报错,因为 b 类中的 a 是私有的,所以会报错并且不会继续往下一个父类中查找 } } class a extends b { int a1 = 10; } class b extends c { private int a = 20; } class c { int a = 30; }
在继承中,我们要调用属性和方法时,会优先从子类中调用属性和方法(注意:构造器则是优先调用父类中的构造器),如果子类中没有,则去父类中调用,依次类推
子类最多只能继承一个父类,因为Java是单继承机制,所以如何让子类继承多个类?
举个例子 有三个类(A、B、C) A继承B,B在继承C,这样A就可以使用C的属性和方法
不能滥用继承,子类和父类必须满足
is-a
的逻辑举个例子 A类表示的是动物 B类表示的是猫 猫是动物 所以 B 类就可以继承 A 类 A类表示的音乐 B类表示的是小狗 小狗不是音乐 所以 B 类就不可以继承 A 类
继承细节
- 调用子类的构造器时会优先调用父类的无参构造器
- 调用子类中的属性或方法时会优先调用子类中的属性和方法,如果子类中没有该属性或方法时再到父类中查找,直到找到为止,如果都没有则会报错
- 每个类中都会有一个默认的无参构造器,只是默认不显示而已,在继承中,构造器里面都会有一个默认的
super();
语句,也是默认不显示,所以当我们调用子类的构造器时,则会优先调用父类里的无参构造器;如果此时父类中有别的有参构造器,那么那个有参构造器就会替换掉默认的无参构造器,所以此时你调用子类的构造器会报错,这时候就需要你使用super()
语句来指定父类中的构造器,这样才不会报错 - 父类不能调用子类中的属性以及方法,但是子类可以调用父类中的属性以及方法(但是也要遵守访问修饰符的权限),除非使用多态这样父类才可以使用子类中的方法(这些方法是子类和父类共有的,就是父类有的方法子类也有,也就是重写),子类的属性则需要使用多态里面向下转型才可以调用