【Java】面向对象进阶-继承
前言
1.之前学过,因此本文是个人复习笔记,为视频的总结以及个人思考,可能不是很详细。
2.教程是b站黑马程序员的JAVASE基础课程,笔记中的大部分图片来自于视频中的PPT截图。
3.Java环境为Java SE 17.0.3.1,IntelliJ IDEA版本为2025.2
https://www.bilibili.com/video/BV1Cv411372m
内容概览
1.本文内容主要包括继承的概念和特点,权限修饰符,单继承,方法重写,子类构造器,以及兄弟构造器。
2.笔记对应视频99-103节
更新记录
无
继承的定义与特点
继承就是用extends关键字,让一个类和另一个类建立起一种父子关系。
子类可以继承父类非私有的成员。对象能直接访问什么成员,是由子父类这多张设计图共同决定的,这多张设计图对外暴露了什么成员,对象就可以访问什么成员。
其过程与之前类似,就是在访问类B时,如果涉及到了A中的变量和方法,会进一步访问类A。

A.java
package com.zbhgis.object3;
public class A {
public int i;
private int j;
public void print1() {
System.out.println("print1");
}
private void print2() {
System.out.println("print2");
}
}
B.java
package com.zbhgis.object3;
public class B extends A {
public int k;
public void print3() {
System.out.println("print3");
System.out.println(i);
print1();
}
}
Object3Demo1.java
package com.zbhgis.object3;
public class Object3Demo1 {
public static void main(String[] args) {
B b = new B();
System.out.println(b.i);
// 不可调用
// System.out.println(b.j);
System.out.println(b.k);
b.print1();
// 不可调用
// b.print2();
b.print3();
}
}
打印结果
0
0
print1
print3
0
print1
继承的好处是可以提高代码的复用性
People.java
package com.zbhgis.object3;
public class People {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Teacher.java
package com.zbhgis.object3;
public class Teacher extends People {
private String skill;
public String getSkill() {
return this.skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
public void printInfo() {
System.out.println(getName() + "具备技能:" + skill);
}
}
Object3Demo2.java
package com.zbhgis.object3;
public class Object3Demo2 {
public static void main(String[] args) {
Teacher t = new Teacher();
t.setName("山");
t.setSkill("MySQL");
System.out.println(t.getName());
System.out.println(t.getSkill());
t.printInfo();
}
}
打印结果
山
MySQL
山具备技能:MySQL
继承的注意事项
权限修饰符
就是是用来限制类中的成员(成员变量、成员方法、构造器、代码块..)能够被访问的范围。

单继承
Java是单继承,即一个类只能继承一个直接父类,不支持多继承,但能多层继承。Object类是Java中所有类的祖宗。
方法重写
使用Override注解,检查我们方法重写的格式是否正确,代码可读性也会更好。
子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限(public>protected>缺省)。
重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
私有方法、静态方法不能被重写。
Student.java
package com.zbhgis.object3;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{name=" + name + ",age=" + age + "}";
}
}
Object3Demo3.java
package com.zbhgis.object3;
public class Object3Demo3 {
public static void main(String[] args) {
Student s = new Student("小明", 20);
System.out.println(s);
}
}
打印结果
Student{name=小明,age=20}
访问的就近原则
1.在子类方法中访问其他成员,是按照就近原则的。
2.如果子父类中,出现了重名的成员,会优先使用子类的;此时通过super关键字可以访问父类成员。
X.java
package com.zbhgis.object3;
public class X {
String name = "父类名称";
public void print1() {
System.out.println("父类的print1");
}
}
Y.java
package com.zbhgis.object3;
public class Y extends X {
String name = "子类名称";
public void showName() {
String name = "局部名称";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
@Override
public void print1() {
System.out.println("子类的print1");
}
public void showMethod() {
print1();
super.print1();
}
}
Object3Demo4.java
package com.zbhgis.object3;
public class Object3Demo4 {
public static void main(String[] args) {
Y y = new Y();
y.showName();
System.out.println();
y.showMethod();
}
}
打印结果
局部名称
子类名称
父类名称
子类的print1
父类的print1
子类构造器
子类构造器的概念和特点
子类的全部构造器都会先调用父类的构造器,再执行自己。
默认情况下,子类全部构造器的第一行代码都是super()(写不写都有),它会调用父类的无参数构造器。
如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(..),指定去调用父类的有参数构造器。
Object3Demo5.java
package com.zbhgis.object3;
class C {
public C() {
System.out.println("父类无参构造器");
}
public C(String name, int age) {
System.out.println("父类有参构造器");
}
}
class D extends C {
public D() {
// super(); // 可不写
System.out.println("子类无参构造器");
}
public D(String name) {
// super(); // 可不写
System.out.println("子类有参构造器");
}
}
class E extends C {
public E() {
super("小明", 6);
System.out.println("子类无参构造器");
}
public E(String name) {
super("小明", 6);
System.out.println("子类有参构造器");
}
}
public class Object3Demo5 {
public static void main(String[] args) {
D d1 = new D();
System.out.println();
D d2 = new D("小明");
System.out.println();
E e1 = new E();
System.out.println();
E e2 = new E("小明");
System.out.println();
}
}
打印结果
父类无参构造器
子类无参构造器
父类无参构造器
子类有参构造器
父类有参构造器
子类无参构造器
父类有参构造器
子类有参构造器
子类构造器的执行原理
将Test2.class和main()方法,以及Teacher类和People类加载到方法区,接下来通过Teacher类创建变量,存储对象,因此栈内存存储变量t,里面的内容为地址,指向堆内存中的对象,通过其类地址找到方法区中的类,找到对应的变量和方法进行创建,进行到super()方法时,进一步前往People类寻找对应的变量和方法进行创建,传回Teacher类,Teacher类创建完所有变量后,再传回到堆内存,此时对象创建完成。之后就是通过get()方法以类似的路径找到变量输出。

Object3Demo6.java
package com.zbhgis.object3;
public class Object3Demo6 {
public static void main(String[] args) {
Friend f = new Friend("明", 16, "小明");
System.out.println(f.getName());
System.out.println(f.getAge());
System.out.println(f.getNickname());
}
}
class Friend extends Person{
private String nickname;
public Friend() {
}
public Friend(String name, int age, String nickname) {
super(name, age);
this.nickname = nickname;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
class Person{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
打印结果
明
16
小明
this兄弟构造器
通过this关键字直接调用兄弟构造器
Object3Demo7.java
package com.zbhgis.object3;
public class Object3Demo7 {
public static void main(String[] args) {
Pet p = new Pet("旺仔", 2.5);
System.out.println(p.getName());
System.out.println(p.getAge());
System.out.println(p.getWeight());
}
}
class Pet{
private String name;
private int age;
private double weight;
public Pet() {
}
public Pet(String name, double weight) {
// 没有提供age的情况,可以这么写,提供默认age
// this.name = name;
// this.age = 1;
// this.weight = weight;
// 也可以this调用兄弟构造器
this(name, 1, weight);
}
public Pet(String name, int age, double weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
打印结果
旺仔
1
2.5
总结
1.修饰符权限:private<缺省<protected<public
2.方法重载是在一个类中,形参列表不同;方法重写是在父类和子类之间,形参列表一致。
3.在子类方法中访问其他成员按照就近原则。
4.子类的全部构造器都会先调用父类的构造器,再执行自己。
5.this()和super()不能够在同一处代码中调用构造器。

浙公网安备 33010602011771号