【Java SE】面向对象三大特性之继承(二)

简介: 【Java SE】面向对象三大特性之继承

🐳 子类构造方法:

子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。

1. //Car.java
2. public class Car {
3. int a;
4. int b;
5.     String name;
6. 
7. public Car(){
8.         System.out.println("基类构造方法");
9.     }
10. 
11. }
12. 
13. //BMW.java
14. public class BMW extends Car{
15. int b;
16. int c;
17. public BMW(){
18.         System.out.println("子类构造方法");
19.     }
20. 
21. 
22. }
23. 
24. //Test.java
25. public class Test {
26. public static void main(String[] args) {
27.      BMW bmw=new BMW();
28.     }
29. }

子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。

注意:

1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现

🐳super和this的区别:

🐳 代码块在继承关系中的执行顺序:

1. //Car.java
2. public class Car {
3. int a;
4. int b;
5.     String name;
6.     {
7.         System.out.println("父类实例代码块执行");
8.     }
9. 
10. static {
11.         System.out.println("父类静态代码块执行");
12.     }
13. public Car(){
14.         System.out.println("基类构造方法执行");
15.     }
16. 
17. }
18. //BMW.java
19. public class BMW extends Car{
20. int b;
21. int c;
22.     String name;
23.     {
24.         System.out.println("子类实例代码块执行");
25.     }
26. 
27. static {
28.         System.out.println("子类静态代码块执行");
29.     }
30. public BMW(){
31.         System.out.println("子类构造方法");
32.     }
33. 
34. 
35. }
36. //Test.java
37. public class Test {
38. public static void main(String[] args) {
39.      BMW bmw=new BMW();
40.     }
41. }

当我们第二次实例化对象的时候,我们可以清楚的看到:

1. public class Test {
2. public static void main(String[] args) {
3.      BMW bmw=new BMW();
4.      System.out.println("第二次实例化子类对象:");
5.      System.out.println("==================================");
6.      BMW bmw1=new BMW();
7.     }
8. }

通过分析执行结果,得出以下结论:
1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

🐳protected 关键字

在封装的那一篇开头介绍了访问控制修饰符:【Java SE】面向对象三大特性之封装

感兴趣的可以再去了解一下。

这边建立了2个不同的包:

其中一个是同一个包中的2个类,另一个类在另一个包中:

首先在同一个包中:

1. package TestDemo;
2. //A.java
3. public class A {
4. public int a;
5. private int b;
6. protected int c;
7. int d;
8. }
9. //B.java
10. package TestDemo;
11. 
12. public class B extends A{
13. 
14. public void method(){
15. 
16. super.a=20;
17. super.b=100;
18. super.c=30;
19. super.d=40;
20. 
21. 
22. }
23. 
24. }

虽然不能访问,但是也继承了父类的b成员变量。

现在是两个包中的:

1. package TestDemo;
2. //A.java
3. 
4. public class A {
5. public int a;
6. private int b;
7. protected int c;
8. int d;
9. }
10. //C.java
11. package TestDemo1;
12. 
13. import TestDemo.A;
14. 
15. public class C extends A {
16. public void method(){
17. 
18. super.a=20;
19. super.b=100; //编译报错,父类中private成员在不同包子类中不可见
20. super.c=30;// 父类中protected修饰的成员在不同包子类中可以直接访问
21. super.d=40;// 父类中默认访问权限修饰的成员在不同包子类中不能直接访问
22. 
23.     }
24. }

注意:我们在使用的时候应该尽可能的使用 比较严格的访问权限. 例如如果一个方法能用 private, 就尽量不要用 public.

🐳继承方式

继承方式有单继承,多层继承和不同类继承同一个类。

一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了.

如果想从语法上进行限制继承, 就可以使用 final 关键字

🐳final 关键字

final关键可以用来修饰变量、成员方法以及类

1. 修饰变量或字段,表示常量(即不能修改)

2. 修饰类:表示此类不能被继承

3. 修饰方法:表示该方法不能被重写

🐳重写

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

要想调用父类中被重写的方法,则必须使用关键字 super。

1. public class Animals {
2. public void call(){
3.         System.out.println("动物叫...");
4.     }
5. }
6. 
7. 
8. public class Cat extends Animals{
9. @Override
10. public void call() {
11.         System.out.println("喵喵喵...");
12.     }
13. }
14. 
15. 
16. public class Dog extends Animals{
17. @Override
18. public void call() {
19. super.call();
20.     }
21. 
22. public static void main(String[] args) {
23. Animals dog = new Dog();
24.         dog.call();//动物叫...
25. Animals cat = new Cat();
26.         cat.call();//喵喵喵...
27.     }
28. }

🐳继承与组合

继承表示对象之间是is-a的关系,比如:狗是动物,猫是动物
组合表示对象之间是has-a的关系,比如:汽车有发动机,轮胎等等组成

1. class D{
2. 
3. }
4. class E{
5. 
6. }
7. //F由D,E构成(组合)
8. class F{
9. private D d; // 可以复用D的属性和方法
10. private E e; // 可以复用E的属性和方法
11. 
12. }

组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合。

相关文章
|
7月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
7月前
|
Java
Java基础语法与面向对象
重载(Overload)指同一类中方法名相同、参数列表不同,与返回值无关;重写(Override)指子类重新实现父类方法,方法名和参数列表必须相同,返回类型兼容。重载发生在同类,重写发生在继承关系中。
199 1
|
7月前
|
存储 Java 关系型数据库
Java 项目实战基于面向对象思想的汽车租赁系统开发实例 汽车租赁系统 Java 面向对象项目实战
本文介绍基于Java面向对象编程的汽车租赁系统技术方案与应用实例,涵盖系统功能需求分析、类设计、数据库设计及具体代码实现,帮助开发者掌握Java在实际项目中的应用。
284 0
|
7月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
1246 1
Java API 开发者
235 0
|
8月前
|
安全 Java 编译器
Java面向对象
本文深入讲解了Java面向对象编程(OOP)的四大特性:封装、继承、多态与抽象,以及方法的设计与使用。通过示例展示了如何用类和对象组织代码,提升程序的可维护性与扩展性。
|
9月前
|
存储 Java 测试技术
Java基础 - 面向对象
面向对象编程是Java的核心,包含封装、继承、多态三大特性。封装隐藏实现细节,提升代码可维护性与安全性;继承实现类间IS-A关系,支持代码复用;多态通过继承、重写与向上转型,实现运行时方法动态绑定,提升系统扩展性与灵活性。
151 0
|
9月前
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
410 1
|
Java
Java 面向对象编程的三大法宝:封装、继承与多态
本文介绍了Java面向对象编程中的三大核心概念:封装、继承和多态。
721 15
下一篇
开通oss服务