从日常到Java中的继承

本文通过生活中的继承概念,解释Java中的类继承机制,包括继承的含义、语法、限制,以及静态属性与一般属性的区别,展示了如何通过`extends`关键字实现子类对父类的扩展和重写。
摘要由CSDN通过智能技术生成

生活中我们提及继承,不难想到继承家业、继承财产等关键词,而且往往它们都是发生在父与子之间的。那么在Java中,什么是继承呢?

当下是一个讲究万物互联的时代,跨学科的思维显得愈发重要,计算机语言也是由程序员开发创造出来的,而程序员也是人,人的思维必然立足于生活,所以在Java语言的一些语法规则中,也必然会体现一些生活中的逻辑(也是我们常说的约定俗成)。

在学习java的过程中,我们往往可以从生活中的现象汲取灵感,从常见的一般化到特殊化,寻找Java语言的异同之处,理解更加深刻与通透。

目录

一、从一张图中走进继承

1.逆向

2.正向

3.结论

二、继承extends

1.继承可以继承什么

1)在类中我们可以定义什么

2)  静态属性与一般属性的异同

3)super关键字的用途

2.代码示例

1)父类代码

2)子类代码


一、从一张图中走进继承

1.逆向

假定我是一个大二的学生,我现在被归为大二类中。

↓( √ )                                                ↓( × )

我同样也可以被归为在大学生类中      我不能被归于大一类中

↓( √ )                                                ↓( × )

我还可以被归在学生类中                    我更不能被归为中学生/小学生类中

即我可以说我是一名大二学生,也可以说我是一名大学生,还可以说我是一名学生。

但是我不能说我是一名大一学生或者中学生了。

2.正向

假设现在已知的信息只有我是一名学生,那么我就可以随便胡诌我是大学生、中学生或者小学生也好,更不用说我是大一学生还是大二学生了。

这里不妨和数学中的集合思维进行结合,但就不做过多阐述了,逐渐养成一个将学过的知识结合起来的习惯(我习惯称之为mix+思维)。

3.结论

1)上级类是下面所有类的父类(大学生类是大一类、大二类的父类,在例子中学生类为最高级)

2)语法上:只允许一个子类直系继承一个父类

→ 理解:一个父亲可以有多个孩子,但一个孩子只能有一个父亲,但同时这个孩子可能还有爷爷。

3)一个对象可以拥有多重身份,且拥有的身份之间需要有继承关系

→ 理解:我可以是一名大二学生的身份,我也可以是一名学生的身份,但在Java中我们需要通过extends关键字来实现它们之间的继承。

二、继承extends

继承是Java面向对象的三大特征(继承、多态、封装)之一。

它可以使得子类具有父类的属性和方法,同时还可以在子类中重新定义,追加新的属性和方法(

子类可以重写override已继承的方法,实现多态性)。

1.继承可以继承什么

1)在类中我们可以定义什么

常见:属性、方法、构造方法、主函数main
不常见:(静态)代码块、静态属性、静态方法(如主函数)、(匿名)内部类

子类可以继承父类的所有的属性和方法吗?

答案自然是肯定不能。

如果你的父亲是一名商人,你作为它的儿子可以继承他的财富但不能继承他的勤奋。

其中静态属性子类和父类共用同一个

→ 理解:儿子继承了父亲的房子,但父亲还是与儿子住在一起。

总的来说父类与子类必有不同,在Java中还可以通过override重写已继承的方法,可以理解为一种“推陈出新”的思想。

对于一些不常见的属性和方法可以参考后续代码示例。

2)  静态属性与一般属性的异同

1.0 存储位置

        静态属性存储在类的静态存储区域中,只会在类加载时初始化一次,并且所有该类的实例共享相同的静态属性值。一般属性存储在每个类的实例(对象)中,每个对象都有自己的一般属性副本,并且属性的值独立于其他对象。

2.0 初始化时机

        静态属性在类加载时被初始化,即使没有创建类的实例,静态属性也会被赋予初始值。
        一般属性属于对象的状态的一部分,只有在创建对象实例时才会为其分配内存并初始化。

3.0 使用方式

  静态属性可以通过类名直接访问,也可以被所有实例共享,通常用于表示与类本身相关的信息,如常量、计数器等。
        一般属性只能通过对象实例来访问,每个对象有自己的一般属性值,通常用于表示对象的特定状态或特征。

3)super关键字的用途

1.0 调用父类的构造方法

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

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

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
    }
}

输出:

Parent class constructor
Child class constructor

2.0 访问父类的成员

class Parent {
    public String name = "Parent";
    
    public void display() {
        System.out.println("Parent class method");
    }
}

class Child extends Parent {
    public String name = "Child";
    
    public void display() {
        System.out.println(super.name); // 访问父类字段
        super.display(); // 调用父类方法
        System.out.println("Child class method");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.display();
    }
}

输出:

Parent
Parent class method
Child class method

3.0 在构造方法中初始化父类特定的属性

在调用构造方法的时候,super()必须放在子类构造方法中的第一行

class Parent {
    private int value;

    public Parent(int value) {
        this.value = value;
    }

    public void display() {
        System.out.println("Parent value: " + this.value);
    }
}

class Child extends Parent {
    public Child(int value) {
        super(value); // 调用父类的带参构造方法
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child(10);
        child.display();
    }
}

输出:

Parent value: 10

2.代码示例

1)父类代码

public class Student {

    static String name;//静态属性

    public void setName(String name){
        this.name=name;
    }

    public Student(){
        System.out.println("父类-构造方法");
        readName();
        wzGlory();
    }

    {
        System.out.println("父类-构造代码块");
    }

    static {
        System.out.println("父类-静态构造代码块,只执行一次");
    }//不创建对象只有主函数入口一样会正常输出

    public static void readName(){
        System.out.println("父类-静态方法,可被类名调用");
    }

    public void wzGlory(){
        System.out.println("父类-铂金段位");
    }

    public static void main(String[] args){
        Student stu = new Student();
        stu.setName("三水气象台");
        System.out.println("父类-name:"+name);

        System.out.println("——————————————————————————");

        Student stu2 = new Student();
        stu2.setName("三水点一灯");
        System.out.println("父类-name:"+name);
    }

}

输出:

父类-静态构造代码块,只执行一次
父类-构造代码块
父类-构造方法
父类-静态方法,可被类名调用
父类-铂金段位
父类-name:三水气象台
——————————————————————————
父类-构造代码块
父类-构造方法
父类-静态方法,可被类名调用
父类-铂金段位
父类-name:三水点一灯

2)子类代码

public class uniStudent extends Student{

    public uniStudent(){
        System.out.println("子类-构造方法");
    }

    {
        System.out.println("——————————————————————————");
        System.out.println("子类-构造代码块");
    }

    @Override //用于检测方法重写是否正确
    public void wzGlory(){
        super.wzGlory();
        System.out.println("子类-星耀段位");
    }

    public static void main(String[] args) {
        uniStudent uniStu = new uniStudent();
        uniStu.setName("子类-紫川秀");
        System.out.println(name);
    }

}

输出:

父类-静态构造代码块,只执行一次
父类-构造代码块
父类-构造方法
父类-静态方法,可被类名调用
父类-铂金段位
子类-星耀段位
——————————————————————————
子类-构造代码块
子类-构造方法
子类-紫川秀


 

  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值