前言
上篇文章给大家简单的介绍了java面向对象继承这一特性,让大家直观明了的知道java继承带给我们的好处。本篇文章给大家带来继承更多的细节,让你们进一步对继承有着深入的理解。
特性一
1. 子类继承了父类所有的属性和方法,但是父类的私有属性在子类中不能直接访问,可以通过公共方法进行访问其私有属性(get方法)。代码示范如下:
定义Base类作为基类,具体如下:
/* Base类为基类 */
public class Base {
public int n1=1;
private int n2=2;
protected int n3=3;
public void method1(){
System.out.println("父类中的被public修饰的method1方法");
}
private void method2(){
System.out.println("父类中的被private修饰的method2方法");
}
protected void method3(){
System.out.println("父类中的被protected修饰的method3方法");
}
/* 访问私有属性*/
public int getN2() {
return n2;
}
/* 访问私有方法*/
public void getMethod2(){
method2();
}
}
定义Sub类继承该基类,具体如下:
/* Sub类为Base的子类 */
public class Sub extends Base{
public void speak(){
//Base父类中非private的方法和属性都可以访问
//被private修饰的方法和属性都不可以访问
System.out.println(n1);
System.out.println(n3);
method1();
method3();
//通过公共方法访问父类私有属性和方法
System.out.println(getN2());
getMethod2();
}
}
Test 类测试:
public class Test {
public static void main(String[] args) {
Sub sub = new Sub();
sub.speak();
}
}
控制台打印输出:
1
3
父类中的被public修饰的method1方法
父类中的被protected修饰的method3方法
2
父类中的被private修饰的method2方法
断点调试
特性二
2. 当使用new关键字创建子类对象时,子类将会先调用父类的构造器,完成父类的初始化。从父类一下往下完成初始化。
编写如下程序,让Sub类继承Base类,当在main函数中new Sub()时,对象初始化流程如下:
轻映录屏 2022-11-29 20-57-26
从上面视频可以看出,当创建子类对象时,会往上找到父类的对象并从父类对象开始进行初始化。
特性三
当创建子类对象时,会默认调用父类的无参无参构造器,如果父类没有提供无参构造器,必须在子类构造器的首行使用supe关键字指定调用父类的构造器,来完成对父类的初始化工作。
编写Base类,并让Sub类继承Base类。
/*父类*/
public class Base {
public int n1=1;
public int n2=2;
public Base() {
System.out.println("父类Base的无参构造被调用了");
}
/*父类的有参构造*/
public Base(int n1) {
this.n1 = n1;
System.out.println("父类Base的有参构造被调用了");
}
}
/*子类*/
public class Sub extends Base{
String s1="李四";
String s2="张三";
public Sub() {
// 此处有个super(); 表示默认调用父类的无参构造,可以不写
System.out.println("子类Sub的无参构造被调用");
}
/*子类的有参构造*/
public Sub(String s1) {
super(6); // 指定调用父类的有参构造
this.s1 = s1;
System.out.println("子类Sub的有参构造被调用");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Sub sub = new Sub();
System.out.println("================");
Sub sub1 = new Sub("小明");
}
}
控制台打印:
父类Base的无参构造被调用了
子类Sub的无参构造被调用
================
父类Base的有参构造被调用了
子类Sub的有参构造被调用
由控制台打印结果可以得知:
- 使用无参构造器初始化创建子类对象时,会默认调用父类的无参构造器,先完成父类的初始化,然后再对子类进行初始化。
- 可以使用 super关键字,显式指定调用父类的构造器,并完成初始化。后期会详讲super关键字用法。
注意:
- 如果我们父类没有无参构造器(当在该类创建无参构造器时,系统不会提供默认的无参构造器,想要无参构造器必须手动创建),子类构造器没有使用super关键字显式调用父类构造器,会出行编译错误。
- 在使用super关键字,必须放在构造器的第一行。
- super和this调用构造器时,不能够同时出现在一个构造器中,他们调用构造器只能放在句首
特性四
java所有的类都是Object类的子类
由此可以得知:
父类构造器的调用不限于直接父类,将一直往上追溯直到Object(顶级父类)
特性五
子类最多只能继承一个父类(直接继承),java中是单继承机制,不类似C++的多继承机制。
小结:
- 子类继承了父类所有的属性和方法,但是父类的私有属性在子类中不能直接访问,可以通过父类提供的公共方法进行访问其私有属性(get方法)。
- 子类必须调用父类的构造器,完成对父类的初始化。
- 当创建子类对象时,会默认调用父类的无参无参构造器,如果父类没有提供无参构造器,必须在子类构造器的首行使用supe关键字指定调用父类的构造器,来完成对父类的初始化工作。
- 如果希望指定的去调用父类的构造器,可以显示使用super关键字进行调用。
- 使用super关键字时,必须放在构造器的第一行。
- java中所有的类都是Object类的子类。
- 父类构造器的调用不限于直接父类。
- java中是单继承机制。
本篇内容给大家带来java面向对象继承中的几点细节。让我们可以清楚的认识到继承带给我们的优点,同时继承使用细节也有很多,在日常的使用中也要牢记,规范使用。下次给大家带来继承创建对象初始化时 JVM的内存分配。