【JAVASE】探索“继承”的奥秘,深入理解JAVA中的继承机制

🔍继承

    • 🎡1. 什么是继承?为啥要继承?
    • 🎡2. 继承的语法
    • 🎡3. 父类成员的访问
      • 🎄3.1 子类中访问父类的成员变量
      • 🎄3.2 super关键字
      • 🎄3.3 super 和 this

🪄在 Java 中,继承是个非常重要的概念,它们是实现代码复用和提高代码灵活性的关键。在这篇博客中,我们将深入探讨这个概念,并通过实例来展示它的实际应用。

🎡1. 什么是继承?为啥要继承?

继承是面向对象编程中的一个重要特性,它允许我们在一个类的基础上创建一个新的类,新的类可以继承原类的属性和方法,并可以添加自己的属性和方法。这种方式可以有效地实现代码复用,减少重复代码的编写。
举例来说明一下吧:

🎉小花家里养了一只可爱的小狗狗和一条有漂亮尾巴的小金鱼,小狗今年3岁,金鱼1岁,小花给小狗取名为“旺财”,给小金鱼取名为“贝贝”,小狗是白色的,金鱼是红色的,小狗会汪汪叫,而金鱼不会叫,小狗吃狗粮,而金鱼吃鱼粮…

通过上述例子,我们可以发现,小狗和小金鱼有许多相同的属性,如都有“名字”,“年龄”,“花色”,当然也有不同的属性或行为,如“吃食不同”,“会不会叫”…
如果我们分开写,写出小狗类,和小金鱼类,我们会发现代码有很多相同的语句,就会显得代码过于冗长。
那能否将这些共性抽取呢?面向对象思想中提出了继承的概念,专门用来进行共性抽取,实现代码复用

🎡2. 继承的语法

有了上面的铺垫,我们就来实战一下,不过在此之前,我们要学习一下继承的语法

🪄在 Java 中,使用 extends 关键字来实现继承。
例如,我们可以定义一个名为 Animal 的类,然后创建一个名为 Dog 类来继承 Animal 类:
class Dog extends Animal
此时Dog 类叫做子类或者派生类Animal 类叫做父类,基类或者超类

具体实现如下:

public class Animal{
	String name;
	int age;
	String color;
	public void sleep(){
		System.out.println(name + "正在睡觉");
	}
} 

public class Dog extends Animal{
	void eat(){
		System.out.println(name + "正在吃狗粮....");
	}
	void bark(){
		System.out.println(name + "汪汪汪~~~");
	}
}

public class Fish extends Animal{
	void eat(){
		System.out.println(name + "正在吃狗粮....");
	}
	void bark(){
		System.out.println(name + "不会叫");
	}
}

在这个例子中,Dog 类 和Fish 类 继承了 Animal 类的所有属性和方法,并且可以添加自己的特有属性和方法。这样,我们就可以将一些通用的属性和方法放在 Animal 类中,然后在 Dog 类中只需要关注狗的特有属性和方法,Fish 类 只需关注鱼特有的属性和方法即可,从而实现了代码的复用

🎡3. 父类成员的访问

🎄3.1 子类中访问父类的成员变量

🌟在子类方法中 或者 通过子类对象访问成员时:

  1. 如果访问的成员变量子类中有,优先访问自己的成员变量。
  2. 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  3. 如果访问的成员变量与父类中成员变量同名,则****优先访问自己的。
    成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找

举个简单的小例子:

public class Base {
	int a;
	int b;
	int c;
} 

public class Derived extends Base{
	int a; // 与父类中成员a同名,且类型相同
	char b; // 与父类中成员b同名,但类型不同
	public void method(){
		a = 100; // 访问子类自己新增的a
		b = 101; // 访问父类继承的b
		c = 102; // 子类没有c,访问的肯定是从父类继承下来的c
		d = 103; // 编译失败,因为父类和子类都没有定义成员变量b
		}
}

🎄3.2 super关键字

由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员, 如果要在子类方法中访问父类同名成员时,该如何操作?直接访问是无法做到的,Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。

🌟【注意事项】

  1. 只能在非静态方法中使用
  2. 在子类方法中,访问父类的成员变量和方法。

也来举个例子吧:

class Parent {
    public int a = 10;
    protected int b = 20;
    int c = 30; // 默认修饰符
    private int d = 40;

    public Parent() {
        System.out.println("Parent constructor called");
    }

    public void printMembers() {
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("c = " + c);
        // System.out.println("d = " + d); // 无法访问,因为 d 是 private 修饰的
    }
}

class Child extends Parent {
    public int e = 50;

    public Child() {
        super(); // 调用父类的构造方法
        System.out.println("Child constructor called");
    }

    public void printMembers() {
        super.printMembers(); // 调用父类的方法
        System.out.println("e = " + e);
    }
}

在上面的示例中, Child 类继承了 Parent 类,并在 Child 类的构造方法中使用 super() 调用了父类的构造方法。在 printMembers() 方法中,使用 super.printMembers() 调用了父类的方法。
此时是不是还是对super关键字不是很理解呢?,没关系,我们再来理解一遍!!!

🥳super 表示的是从父类继承过来的数据的引用,指定告诉编译器,我们访问的是父类的成员或方法
super 的出现,增强代码的可读性

🌟注意:

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

🎄3.3 super 和 this

😊【相同点】

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

🤕【不同点】

  1. this当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用
  2. 非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
  3. 构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造
    方法中出现
  4. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

🥳OK,今日分享就到这里啦,上述如有错误,还请各位大佬给予指正,一定及时修改!!!✌️

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2023年12月7日
下一篇 2023年12月7日

相关推荐