【Java继承】(超级详细!!!)
- 1、 继承的概念
- 2 、继承的语法
- 3、 父类成员访问
- 3.1 子类中访问父类的成员变量
- 3.2 子类中访问父类的成员方法
- 4、 super关键字
- 5 、子类的构造方法
- 6、 继承关系上的执行顺序
- 7、protected 关键字
- 8、继承方式
- 9、final 关键词
1、 继承的概念
继承机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。
例如:小猫和小狗都是(有名字有年龄要吃饭)的动物。
上述图示中,Dog和Cat都继承了Animal类。
其中:Animal类称为父类/基类或超类,Dog和Cat可以称为Animal的子类/派生类。
继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。
下面我们将学习继承的语法,利用代码实现上述继承关系!
2 、继承的语法
修饰符 class 子类名 extend 父类名(){//...
}
注意:
- 子类会将父类中的成员变量或者成员方法继承到子类中
- 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了
3、 父类成员访问
3.1 子类中访问父类的成员变量
- 如上图a所示:当子类和父类中同时有成员变量a时,访问的是子类的成员变量a
- 如上图b所示:当子类没有成员变量b,而父类有成员变量b时,访问的是父类的成员变量b
- 如上图c所示:当子类有成员变量c,父类没有成员变量c时,访问的是子类的成员变量c
注意:
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。
3.2 子类中访问父类的成员方法
- 如上图test1所示:子类中没有成员方法test1,父类中有成员方法test1,所以访问的是父类中的成员方法test1
- 如上图test2所示:子类中有成员方法test2,父类中没有成员方法test2,所以访问的是子类中的成员方法test2
- 如上图test所示:子类和父类都有成员方法test,同样遵循就近原则,访问的是子类的成员方法test
下面我们进行一个小测试,从而使我们更深入的了解该知识点。
//父类
public class Father {int a=1;int b=1;public void test1(int a){System.out.println("父类test1,数字结果为:"+a);}public void test1(){System.out.println("父类test1,无参数");}}
//子类
public class Son extends Father{int a=2;int c=2;public void test1(){System.out.println("子类test1,无参数");}public void func(){test1();test1(a+c);test1(b+c);}
}
//主函数
public class Main {public static void main(String[] args) {Son son=new Son();son.func();}
}
打印结果:
子类test1,无参数
父类test1,数字结果为:4
父类test1,数字结果为:3
4、 super关键字
通过上述知识我们知道:当子类和父类中存在相同名称的成员时,访问子类的成员。
那么,,如果要在子类方法中访问父类同名成员时,该如何操作?
此时便需要用到关键词super
- super只能在非静态方法中使用
- 在子类方法中访问父类的成员变量和方法
super的用法远不止这些,super的其他方法会在下文中提到。
5 、子类的构造方法
- 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
- 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
- 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。
- super(…)只能在子类构造方法中出现一次,并且不能和this同时出现
6、 继承关系上的执行顺序
//父类
public class Father1 {int a;int b;//构造方法public Father1(int a, int b) {this.a = a;this.b = b;System.out.println("父类,构造方法");}{System.out.println("父类,实例方法");}static {System.out.println("父类,静态方法");}
}
//子类
public class Son extends Father1 {public Son(int a, int b) {super(a, b);System.out.println("子类,构造方法");}{System.out.println("子类,实例方法");}static {System.out.println("子类,静态方法");}
}
//主方法
public class Main {public static void main(String[] args) {Son son=new Son(1,2);System.out.println("=============");Son son1=new Son(1,2);}
}
打印结果:
父类,静态方法
子类,静态方法
父类,实例方法
父类,构造方法
子类,实例方法
子类,构造方法
=============
父类,实例方法
父类,构造方法
子类,实例方法
子类,构造方法
由上述代码可以得出结论:
- 首先依次执行父子类的静态方法
- 接着依次进行父类的实例方法和构造方法
- 最后依次进行子类的实例方法和构造方法
- 静态方法只执行一次
7、protected 关键字
1.同一包中的同一类
2.同一包的不同类
3.不同包中的子类
4.不同包中的非子类
8、继承方式
注意:Java不能实现多继承!!!
9、final 关键词
1.final 修饰变量或字段
2.final 修饰类
3.final 修饰方法