继承
继承是面向对象的三大特征之一
继承的作用:
基本的作用是:代码复用
重要的作用是:有了继承才有了以后方法的覆盖和多态机制
继承的语法结构:
[修饰符列表] class 类名 extends 父类名{ 类体 = 属性 + 方法 }
java语言中的继承只支持单继承,一个类不能同时继承多个类,只能继承一个类,[C++中支持多继承]
java不允许多重继承,但是运行多层继承,一般不要超过三层的继承关系
继承的相关术语: B类继承A类,其中:
A类称为:父类、基类、超类、superclass
B类称为:子类、派生类、subclass
在java中子类继承父类继承那些数据?
私有的不支持继承
构造方法不支持继承
其他数据都可以继承
严格来讲会继承父类的所有操作,但是除了私有的(隐性的)
虽然Java语言中只支持单继承,但是一个类也可以间接继承其他类,列如:
C extends B{ } B extends A{ } A extends T{ } //C直接继承B类,但是C类间接继承T、A类。
Java语言中假设一个类没有显示继承任何类,默认继承JDK/JavaSE库当中提供的java.lang.Object类,Java语言中任何一个类中都有Object类的特征
代码
public class 继承 { public static void main(String[] args) { 继承 e = new 继承(); String s = e.toString(); //这里编译通过了,说明可以调用toString方法,【继承】类中有toString方法,从Object类中继承过来的 System.out.println(s); //com.Static.继承@15db9742 } }
继承
继承的限制
利用extends关键字在大部分的情况下都可以不用考虑给出的继承限制(前提:按照标准格式开发),但是事实上由于限制用户的使用,所以针对继承也有一些自己的要求。
Java不允许多继承
在c++语言之中具备一种概念 ———— 多继承,即:一个子类可以以同时继承多个父类。但是如果希望实现一个子类继承多个父类的操作,那么可以使用————多层继承
public class 继承 { public static void main(String[] args) { C c = new C(); c.doSome(); //调用的doSome方法是从B继承的方法 } } class A { public void doSome() { System.out.println("do some"); } } class B extends A { } class C extends B { }
相当于C是B的子类,是A的孙子类。在使用多层继承的时候并没有层数限制,不过从开发的角度认为,不要超过三层。
子类在继承父类的时候严格来讲会继承父类中的全部操作,但是对于所有的私有操作属于隐式继承,而非私有操作属于显式继承。
观察属性
public class 私有继承演示 { public static void main(String[] args) { b b = new b(); b.setMsg("hello"); System.out.println(b.getMsg()); } } class a{ private String msg ; //私有属性 public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } class b extends a{}
在b类里面一定是存在有msg属性,因为如果不存在,那么setMsg()设置的内容就不可能保存,即:getMsg()是觉得无法进行内容输出。 但是在b类里面不能够针对于msg进行访问,因为它是私有的,只能够间接地进行私有属性的访问。
在子类对象构造之前一定会默认调用父类的构造(默认使用无参构造),以保证父类的对象先实列化,而后实列化子类对象。
public class 调用构造 { public static void main(String[] args) { new b1(); // 实列化子类对象 } } class a1{ public a1(){ System.out.println("A、A类的构造"); } } class b1 extends a1{ public b1(){ System.out.println("B、B类的构造"); } }
此时没有添加任何的操作代码,但是可以发现,在实列化子类对象前先去实列化了父类对象以及调用了父类的无参构造。 那么此时对于子类的构造而言,就相当于隐含了一个super().
public class 调用构造 { public static void main(String[] args) { new b1(); // 实列化子类对象 } } class a1{ public a1(){ System.out.println("A、A类的构造"); } } class b1 extends a1{ public b1(){ super(); // 父类中有无参构造时,加与不加无区别。 System.out.println("B、B类的构造"); } }
父类中有无参数构造时,加与不加无区别,如果说此时父类中没有无参数构造了,那么就必须使用super()明确调用父类的有参构造。
public class 调用构造 { public static void main(String[] args) { new b1("hello"); // 实列化子类对象 } } class a1{ public a1(String title){ System.out.println("A、A类的构造"); } } class b1 extends a1{ public b1(String title){ super(title); // 父类中有无参构造时,加与不加无区别。 System.out.println("B、B类的构造"); } }
通过观察发现super()主要是由子类调用父类中的构造方法,那么这行语句一定要放在子类的构造方法的首行,这一点和this()是类似的。 疑问? 既然super()和this()都放在首行,又说过,如果现在子类构造没有编写super()的话,会自动使用一个super()调用父类的无参构造,那么如果写上了this(),那么是不是就表示子类无法调用无参构造了呢? 通过代码验证: super()与this()不能同时出现,不管子类怎么折腾,他都永恒有一个存在的前提:子类对象的构造调用前一定要先执行父类构造,为父类的对象初始化后才轮到子类的对象初始化。
- 上一篇: 为什么静态方法无法调用非静态成员
- 下一篇: 全国哀悼——缅怀抗疫英雄
评论