JavaSE之面向对象之继承

继承概述

  1. 继承是类与类之间的一种关系
  2. 多个类继承单独的某个类,多个类就可使用单独的这个类的属性和行为了
  3. 多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)
    使用继承的好处:提高代码的复用
    请添加图片描述
    请添加图片描述
public class People {
    private String name;
    private int 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;
    }
}

public class Student extends People{
    /**
     * 独有的行为
     */
    public void study(){
        System.out.println("学生"+getName()+getAge()+"岁了,能好好学习了~~~");
    }
}
public class Teacher extends People{
    /**
     * 独有的行为
     */
    public void teach(){
        System.out.println("老师"+getName()+getAge()+"岁了,在教书育人~~~");
    }
}
public class Test {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(22);
        s1.study();
        Teacher t1 = new Teacher();
        t1.setName("李四");
        t1.setAge(30);
        t1.teach();
    }
}

请添加图片描述
请添加图片描述

继承的设计规范、内存运行原理

继承设计规范

子类们相同特征放在父类中定义,子类独有的属性和行为应该定义在子类自己里面

案例——继承的规范

需求

在教育的tlias的教学资源管理系统中,存在学生,老师角色会进入系统

分析

  1. 学生信息和行为(名称,年龄,所在班级,查看课表,填写听课反馈)
  2. 老师信息和行为(名称,年龄,部门名称,查看课表,发布问题)
  3. 定义角色类作为父类包含属性(名称,年龄),行为(查看课表)
  4. 定义子类:学生类包含属性(所在班级),行为(填写听课反馈)
  5. 定义子类:老师类包含属性(部门名称),行为(发布问题)
public class People {
    private String name;
    private int 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;
    }

    public void viewSchedule(){
        System.out.println(name+"查看课程表");
    }

}

public class Student extends People{
    private String aclass;

    public String getAclass() {
        return aclass;
    }

    public void setAclass(String aclass) {
        this.aclass = aclass;
    }

    public void Feedback(){
        System.out.println(getName()+"在"+getAclass()+"班今天学习也是美美的");
    }

}
public class Teacher extends People{
    private String ePart;

    public String getePart() {
        return ePart;
    }

    public void setePart(String ePart) {
        this.ePart = ePart;
    }

    public void postQues(){
        System.out.println(getName()+"在"+getePart()+"教学感觉有点问题!");
    }
}
public class Test {
    public static void main(String[] args) {
        Student s1=new Student();
        s1.setName("张三");
        s1.setAclass("11班");
        s1.setAge(22);
        s1.viewSchedule();
        s1.Feedback();
        Teacher t1=new Teacher();
        t1.setName("李四");
        t1.setAge(30);
        t1.setePart("教师部");
        t1.viewSchedule();
        t1.postQues();
    }
}

请添加图片描述
请添加图片描述

继承的特点

  1. 子类可以继承父类的属性和行为,但是子类不能继承父类的构造器
  2. Java是单继承模式:一个类只能继承一个直接父类
  3. Java不支持多继承,但是支持多层继承
  4. Java中所有的类都是Object类的子类

注意

  1. 子类不可以继承父类的构造器
  2. 子类可以继承父类的私有成员,只是不能直接访问
  3. 子类可以直接使用父类的静态成员,只是共享,不算继承

Object特点

  1. Java中所有类,要么直接继承了Object,要么默认继承了Object,要么间接继承了Object,Object是祖宗类
public class test{
    public static void main(String[] args) {
        Tiger t=new Tiger();
        t.speak();
        t.say();
        System.out.println(Tiger.location);
    }
}

class Animal{
    public void speak(){
        System.out.println("我是动物");
    }
    public static String location="长隆动物园";
}

class Tiger extends Animal{
    public void say(){
        System.out.println("我是老虎");
    }
}

请添加图片描述

继承后:成员变量、成员方法的访问特点

在子类方法中访问成员(成员变量、成员方法)满足 就近原则

  1. 先子类局部范围找
  2. 然后子类成员范围找
  3. 然后父类成员范围找,如果父类范围还没有找到则报错
    如果子父类中,出现了重名的成员,会优先使用子类的,如果要使用父类的,可以通过super关键字,指定访问父类的成员
public class demo3 {
    public static void main(String[] args) {
        Dog d=new Dog();
        d.run();
        d.dogLookDoor();
        d.showMess("笨笨");
    }


}

class Animal{
    public String name="动物名";
    public void run(){
        System.out.println("动物可以跑步~~");
    }
}

class Dog extends Animal{
    public String name="狗名";

    public void dogLookDoor(){
        System.out.println("狗可以看门");
    }

    public void run(){
        System.out.println("狗可以跑步");
    }

    public void showMess(String name){
        System.out.println("name:"+name);
        System.out.println("this.name:"+this.name);
        System.out.println("super.name:"+super.name);
        run();
        super.run();
    }
}

请添加图片描述

继承后:方法重写

在继承体系中,子类出现了和父类中一模一样的方法声明,我们就称子类这个方法是重写的方法

方法重写的应用场景

当子类需要父类的功能,但父类的该功能不完全满足自己的需求时
子类可以重写父类中的方法

案例演示

  1. 旧手机的功能只能是基本的打电话,发信息
  2. 新手机的功能需要能够:基本的打电话下支持视频通话,基本的发信息下支持发送语音和图片

重写方法注解
@Override

  1. 重写校验注解,加上之后,这个方法必须是正确重写的,这样更安全
  2. 提高程序的可读性,代码优雅!
package com.echo.demo;

import junit.framework.TestCase;

public class demo4 extends TestCase {
    public static void test(){
        NewPhone newPhone = new NewPhone();
        newPhone.call();
        newPhone.send();
    }
}

class OldPhone{
    public void call(){
        System.out.println("打电话");
    }
    public void send(){
        System.out.println("发信息");
    }
}

class NewPhone extends OldPhone{
    @Override
    public void call(){
        super.call();
        System.out.println("还能视频通话");
    }
    @Override
    public void send(){
        super.send();
        System.out.println("还能发送语音和图片");
    }
}

请添加图片描述

方法重写注意事项和要求

  1. 重写方法的名称、形参列表必须与被重写方法的名称和参数列表一致
  2. 私有方法不能被重写
  3. 子类重写父类方法时候,访问权限不行大于或者等于父类
  4. 子类不能重写父类的静态方法,如果重写会报错的

继承后:子类构造器的特点

特点

子类中所有的构造器默认都会先访问父类中无参的构造器,再执行自己
原因:

  1. 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据
  2. 子类初始化之前,一定要调用父类构造器先完成父类数据空间的初始化
    子类构造器的第一行语句默认都是:super(),不写也存在
package com.echo.demo;

public class demo5 {
    public static void main(String[] args) {
        Girl girl = new Girl();
        System.out.println(girl);
        Girl girl1 = new Girl("小芳");
        System.out.println(girl1);
    }
}

class Person{
    public Person(){
        System.out.println("父类的无参构造器");
    }
}
class Girl extends Person{
    public Girl(){
//        super();  不写也存在
        System.out.println("子类的无参构造器");
    }
    public Girl(String name){
        System.out.println("子类的有参数构造器");
    }
}

请添加图片描述

super调用父类有参数构造器

作用:
初始化继承自父类的数据

package com.echo.demo;

public class demo6 {
    public static void main(String[] args) {
        Teacher t = new Teacher("张三", 20);
        System.out.println(t.getName());
        System.out.println(t.getAge());
    }
}

class People{
    private String name;
    private int age;

    public People() {
    }

    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 People(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Teacher extends People{
    //调用父类的有参数构造器,初始化继承自父类的数据
    public Teacher(String name,int age){
        super(name,age);
    }
}

请添加图片描述
如果父类中没有无参数构造器,只有有参构造器,会报错的,因为子类默认是调用父类无参数构造器的,除非子类构造器中通过书写super(…)手动调用父类的有参数构造器。
请添加图片描述

案例需求

  1. 在学员信息登记系统中,后台创建对象封装数据的时候如果用户没有输入学校,则默认使用“西安中学”
  2. 如果用户输入了学校则使用用户输入的学校信息
public class demo7 {
    public static void main(String[] args) {
        User u1=new User("张三","西安一中");
        User u2=new User("李四");
        System.out.println("u1.getName:"+u1.getName());
        System.out.println("u1.getSchool:" + u1.getSchool());
        System.out.println("u2.getName:"+u2.getName());
        System.out.println("u2.getSchool:" + u2.getSchool());
    }
}

class User{
   private String name;
   private String school;

    public String getName() {
        return name;
    }

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

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }


    //有参数构造器
    public User(String name,String school){
        this.name=name;
        this.school=school;
    }

    //如果用户没有输入学校则这样写
    public User(String name){
        this(name,"西安中学");
    }
}

请添加图片描述
this()和super()使用注意点
子类通过this(…)去调用本类的其他构造器,本类其他构造器会通过super去手动调用父类的构造器,最终还是会调用服了的构造器的

注意
this(…)和super(…)都只能放在构造器的第一行,所以二者不能共存在同一个构造器中

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值