【Java】继承1

简介: 【Java】继承

1.为什么需要继承

说起继承大家会想起什么,想到子女继承了父母的哪些优秀品质。那就说明子女和父母一样拥有这些品质。


Java中的类是对现实事物的描述,通过对类的实例化就会产生对象。世间事物千千万万,那么有些事物一定会存在一定的联系。


比如有一个狗类,有一个猫类:


//狗类
class Dog {
    public String name;
    public int age;
    public void dogCall() {
        System.out.println(name+"汪汪汪");
    }
    public void eat() {
        System.out.println(name+"吃饭饭");
    }
}
//猫类
class Cat {
    public String name;
    public int age;
    public void catCall() {
        System.out.println(name+"喵喵喵");
    }
    public void eat() {
        System.out.println(name+"吃饭饭");
    }
}

通过观察上述的狗类和猫类,我们可以发现它们有许多相同的成员变量和成员方法


为了避免大量的重复:面向对象思想中提出了继承的概念,继承就是专门用来共性抽取,实现代码复用


2.继承的概念

继承机制:是面向对象程序设计使代码达到复用的最重要手段,它允许类在保持原有的特性上加以扩展,增加新功能,这样产生的新类就叫做派生类。


去.png


将 Dog 类 和 Cat类 的相同的成员放入一个类中 ,那么这个类就是动物类因为动物都有这些特征,狗和猫也都是动物。动物类在保持原有的特性上加以扩展,增加 Dog 的新功能,就有了 Dog 类,那么 Dog类需要继承动物类,这样 Dog 类才能继承动物类的一些成员,也就达到了代码的复用。Cat 类也是同样的道理。


Dog类 和 Cat类 都继承了 Animal类

Animal类 就称为父类 / 基类 / 超类

Dog类 和 Cat类 就称为子类 / 派生类

继承之后子类可以复用父类的成员,子类在实现时只需关心自己新增加的成员

继承:共性的抽取,实现代码复用


3.继承的语法

子类只有继承了父类,才可以复用父类的成员,那么子类应该如何继承父类呢?


通常借助 extends 关键字,来实现类之间的继承


class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println(name+"吃饭");
    }
}
class Dog extends Animal {
    public void dogCall() {
        System.out.println(name+"汪汪汪");
    }
}

这样 Dog类 也就成功继承了 Animal类


我们知道实例化一个类的时候,实例化而成的对象在堆上存放的是成员变量


当我们执行这句代码时:


Dog dog = new Dog();

实例化出来的 dog 对象在堆上存放的又该是什么咧?

请.png



我们可以通过这个解析图可以理解,当我们实例化一个 Dog 类是,dog 对象在堆里面不仅会存放自己的成员变量,还会存放继承父类的成员变量


子类会将父类中的成员变量或成员方法继承到子类中了

子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承

4.父类成员访问

子类将父类的成员继承了下来,那么子类是否可以访问继承下来的父类成员


4.1子类中访问父类的成员变量

①访问父类中与子类不同名的成员变量:直接访问


class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println(name+"吃饭");
    }
}
class Dog extends Animal {
    public String colour;
    public void dogCall() {
        name = "阿黄";
        System.out.println(name+"汪汪汪");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.dogCall();
    }
}

子类如果访问父类不同名的成员变量可以直接访问


注:


当父类的成员变量为 private 修饰时,我们知道 private 修饰的成员变量只能在同一个包中同一个文件中同一个类中使用,那么此时子类如何访问父类的成员变量了?


其.png


因为 age 成员变量是 private 修饰的,所以 age 只能在 Animal 类中使用。即使 Dog 继承了Animal 类,也不能使用


private 修饰的成员变量可以继承,但不能访问


如果想要使用 private 修饰 age 成员变量,可以在 Animal 里面写一个返回 age 的成员方法:


class Animal {
    public String name;
    public int age;
    public void eat() {
        System.out.println(name+"吃饭");
    }
    public int setAge(int age) {
        this.age = age;
        return this.age;
    }
}
class Dog extends Animal {
    public String colour;
    public void dogCall() {
        name = "阿黄";
        System.out.println(name+setAge(1)+"汪汪汪");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.dogCall();
    }
}


写一个返回 age 的成员方法,我们便可以使用 age 里面的值了


②访问父类中与子类同名的成员变量


class Animal {
    public String name = "阿黄";
    public void eat() {
        System.out.println(name+"吃饭");
    }
}
class Dog extends Animal {
    public String name = "阿福";
    public void dogCall() {
        System.out.println(name+"汪汪汪");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.dogCall();
    }
}

打印结果:


前.png


上述代码中父类有一个 name 成员变量,子类也有一个 name 成员变量,且它们的类型都相同。我们通过子类中的成员方法打印可以发现,打印的是子类中的 name 成员变量的值


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


如果访问的成员变量子类中有,优先访问子类自己的成员变量

如果访问的成员变量子类中没有,就访问父类继承下来的成员变量。如果父类也没有,则编译报错

如果访问的成员变量与父类的成员变量同名,则优先访问子类自己的成员变量

注:成员变量的访问遵循就近原则,自己有则优先访问自己的,如果没有则向父类中找


4.2子类中访问父类的成员方法

①访问父类中与子类不同名的成员方法


class Animal {
    public String name = "阿黄";
    public void eat() {
        System.out.println(name+"吃饭");
    }
}
class Dog extends Animal {
    public String name = "阿福";
    public void dogCall() {
        eat();
        System.out.println(name+"汪汪汪");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.dogCall();
    }
}


运行结果:

我.png



当通过 子类的成员方法 或者 通过子类的对象 访问父类中与子类不同名的成员方法,则直接访问


②访问父类中与子类同名的成员方法


class Animal {
    public String name = "阿黄";
    public void eat() {
        System.out.println(name+"吃饭");
    }
}
class Dog extends Animal {
    public String name = "阿福";
    public void eat() {
        System.out.println(name+"吃狗粮");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
    }
}


运行结果:

为.png



当通过 子类的成员方法 或者 通过子类的对象 访问父类中与子类同名的成员方法,则会优先访问子类的成员方法


通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。

通过子类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法传递的参数选择合适的方法访问,如果没有则报错

那么现在就有这样一个问题了:


如果子类和父类的成员变量或成员方法相同,我们如何通过子类的成员方法,去访问与父类中与子类相同的成员变量或者成员方法呢?


5.super关键字

上面我们留下了这样一个问题,当子类与父类的成员相同时,我们如果通过子类的方法去访问,一定会访问子类的成员。 那么我们应当如何通过子类的方法去访问父类与子类相同的成员呢?


我们可以通过 super 关键字去访问父类的成员不论与子类相不相同,都可以用 super 去访问


super关键字主要作用:在子类方法中访问父类的成员


如果我们在子类中看到了 super 关键字,那么它一定是在访问父类中的成员


class Animal {
    public String name = "阿黄";
    public void eat() {
        System.out.println(name+"吃饭");
    }
}
class Dog extends Animal {
    public String name = "阿福";
    public void eat() {
        System.out.println(super.name+"吃狗粮");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
    }
}

运行结果:

五.png



我们可以看到上述的代码中在 Dog 类中的 eat 方法里面,我们打印的时候用来 super.name。那么打印的时候一定用的是父类中的 name,通过运行结果我们也可以看出来的确打印的是父类中的 name


super 关键字只能在非静态方法中使用

super 关键字在子类方法中,访问父类的成员变量和方法


相关文章
|
3天前
|
Java
Java中的继承和多态是什么?请举例说明。
Java中,继承让子类继承父类属性和方法,如`class Child extends Parent`,子类可重写父类方法。多态允许父类引用指向子类对象,如`Animal a = new Dog()`,调用`a.makeSound()`会根据实际对象类型动态绑定相应实现,增强了代码灵活性和可扩展性。
14 0
|
3天前
|
Java
Java基础—笔记—继承篇
该内容介绍了Java中的继承概念。继承允许子类从父类继承属性和方法,简化代码并提高复用性。格式是`public class 子类 extends 父类`。特点包括子类能访问非私有数据,方法可以被重写(@Override标记),但私有和静态方法不能重写。权限修饰符有private、缺省、protected和public。Java支持单继承和多层继承,所有类间接继承自Object类。继承后,成员访问遵循就近原则,this指代本类,super指代父类。子类构造器默认调用父类无参构造器,也可通过super调用有参构造器。
18 0
|
3天前
|
Java
在Java中,多态性是通过继承和接口实现的
【4月更文挑战第7天】在Java中,多态性是通过继承和接口实现的
22 1
|
3天前
|
搜索推荐 Java
Java的面向对象特性主要包括封装、继承和多态
【4月更文挑战第5天】Java的面向对象特性主要包括封装、继承和多态
21 3
|
3天前
|
Java
【Java开发指南 | 第二十四篇】Java继承
【Java开发指南 | 第二十四篇】Java继承
9 0
|
3天前
|
Java
【Java开发指南 | 第九篇】访问实例变量和方法、继承、接口
【Java开发指南 | 第九篇】访问实例变量和方法、继承、接口
14 4
|
3天前
|
Java
【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态
【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态
|
3天前
|
Java 编译器 开发者
Java一分钟之-继承:复用与扩展类的特性
【5月更文挑战第9天】本文探讨了Java中的继承机制,通过实例展示了如何使用`extends`创建子类继承父类的属性和方法。文章列举了常见问题和易错点,如构造器调用、方法覆盖、访问权限和类型转换,并提供了解决方案。建议深入理解继承原理,谨慎设计类结构,利用抽象类和接口以提高代码复用和扩展性。正确应用继承能构建更清晰、灵活的代码结构,提升面向对象设计能力。
17 0
|
3天前
|
Java
java面向对象——包+继承+多态(一)-2
java面向对象——包+继承+多态(一)
18 3
|
3天前
|
SQL Java 编译器
java面向对象——包+继承+多态(一)-1
java面向对象——包+继承+多态(一)
17 2