为了有助于大家更好的理解博文内容,在此附上博主相应的码云和github地址,每篇文章相关的代码都在里面,在本博客中放在第一行,以后为了不妨碍阅读都会放到最后一段。
在 Java 面向对象编程的世界里,继承与多态是两大核心特性,它们让代码具备更好的复用性、扩展性与灵活性。本文将深入剖析 Java 继承的关键知识点,带你领略面向对象编程的魅力。
在软件开发中,常常会遇到多个类存在相同属性和方法的情况。比如定义 “动物” 相关类,“猫”“狗” 都有 “名字”“年龄” 属性,也有 “吃饭”“睡觉” 方法。如果每个类都重复编写这些代码,既冗余又不利于维护。继承就是为了解决这个问题而生,它允许子类复用父类的属性和方法,让代码更简洁高效 。
继承是一种 is - a 关系,子类(subclass)继承父类(superclass),子类可以获得父类非私有(private 修饰的无法直接继承)的属性和方法,还能扩展自身特有的功能。例如,“狗” 类继承 “动物” 类,“动物” 类是父类,“狗” 类是子类,“狗” 除了有动物的通用特征,还可有 “汪汪叫” 等专属行为 。
在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下
package demo2;
//父类
public class Base {
public int a = 1;
public int b = 2;
}package demo2;
//子类
public class Derived extends Base{
public int c = 3;
public void func(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}package demo2;
public class Test {
public static void main(String[] args) {
Derived derived = new Derived();
derived.func();
}
}
但如果子类中定义一个重名的成员变量会优先考虑子类中的成员变量
package demo2;
public class Derived extends Base{
public int c = 3;
public int a = 4;
public void func(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
如果仍然想访问父类的成员变量,需要加super关键字
package demo2;
public class Derived extends Base{
public int c = 3;
public int a = 4;
public void func(){
System.out.println(super.a);
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
访问父类的方法同样也用super
super关键字在子类中作用关键,用于访问父类成员:
访问父类属性:super.属性名,解决子类与父类属性同名时的歧义。 访问父类方法:super.方法名(参数),当子类重写父类方法后,想调用父类原本的实现,就靠它。 调用父类构造器:super(参数),且必须放在子类构造器第一行,用于初始化父类部分
前两点易于理解,第三点是指在父类和子类都自定义了构造方法时(不自定义java会自动默认定义好)子类继承父类时,要显示的调用父类的构造方法,先帮助父类成员初始化 父类:
package demo1;
public class Animal {
private String name;
private int age;
static{
System.out.println("static::Animal");
}
{
System.out.println("实例化代码块::Animal");
}
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 Animal(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Animal构造方法");
}
}子类:
package demo1;
public class Cat extends Animal{
static{
System.out.println("static::Cat");
}
{
System.out.println("实例化代码块::Cat");
}
public Cat(String name, int age) {
//System.out.println();
super(name,age);//必须在第一行
System.out.println("Cat构造方法");
}
}===================================================
package demo1;
public class Test {
public static void main(String[] args) {
Cat cat = new Cat("mimi",7);
}
}执行这段代码,运行结果会如何呢?

看到这个结果大家可能会很难理解,可以使用之前博客教的调试方法走一遍过程就能理解了,像下面这样:

具体代码去博主马云仓库里找哦
小补充

子类继承父类后,访问父类成员有不同规则:
public、protected 修饰的成员:子类可直接访问,像父类用protected修饰的age属性,子类里能直接使用。 default(包访问权限,无显式修饰符)成员:子类得和父类在同一包中,才能访问。 private 成员:子类无法直接访问,若要使用,得借助父类提供的public或protected方法间接获取。比如父类有个private的weight属性,可写个public int getWeight()方法,子类通过调用该方法拿到weight值 。
其他的都了解,重点说protected:


简而言之,不同包中的两个类若是父子类,子类可以访问父类protected修饰的变量
final关键可以用来修饰变量、成员方法以及类。 1. 修饰变量或字段,表示常量(即不能修改)
final int a = 10;
a = 20; // 编译出错2. 修饰类:表示此类不能被继承
final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 编译出错
Error:(3, 27) java: 无法从最终com.bit.Animal进行继承继承:是 “is - a” 关系,侧重代码复用,不过可能增加类的耦合度。 组合:是 “has - a” 关系(一个类包含另一个类的对象,如 “汽车” 类包含 “发动机” 类对象 ),更灵活,能动态替换包含的对象,降低类依赖。实际开发中,要根据需求合理选,复杂系统里组合常能让代码更易维护扩展
继承是 Java 面向对象编程的重要基石,合理运用它,能让代码简洁、可复用。但也要注意继承带来的耦合问题,结合组合等设计思想,打造出更优秀的软件系统。掌握继承的这些知识,你在 Java 编程的道路上又迈出坚实一步,后续面对复杂类设计,也能游刃有余 。