4.1 继承性

知识回顾

(1)类和对象的理解?

对象是现实世界中的一个实体,如一个人、一辆汽车。一个对象一般具有两方面的特征,状态和行为。状态用来描述对象的静态特征,行为用来描述对象的动态特征。

类是具有相似特征和行为的对象的集合,是对象共同特征的描述。

类和封装的关系:类是对象的抽象,对象(通常也称实例)是类的一个具体实例。

(2)面向对象三大特性?

封装、继承和多态。

(3)封装性的理解?

封装性一方面是把对象的属性和行为看成一个密不可分的整体,将这两者“封装”在一个不可分割的独立单元中;另一方面是将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

1.1. 继承的概念

(1)现实中的继承

现实生活中,说到继承,通常会想到子女继承父辈的财产、事业等。

4.1 继承性_第1张图片

(2)程序中的继承

在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。例如,老师和学生都属于人类,程序中便可以描述为:老师和学生继承自人类,同理,体育老师和美术老师继承自老师,而专科生和本科生继承自学生。

4.1 继承性_第2张图片

1.2. 继承的思路

(1)为什么要使用继承

思考,如下两个类有什么问题或可优化点呢?Student和Teacher类中存在着相同的成员变量和成员方法。

4.1 继承性_第3张图片

(2)使用继承优化设计

使用继承优化设计,将Student和Teacher类中重复的代码提取到父类(Person)中。

4.1 继承性_第4张图片

(3)使用继承优化后

继承提高了代码的复用性,多个类相同的成员可以放到同一个类中;提高了代码的维护性,如果方法的代码需要修改,修改一处即可。

4.1 继承性_第5张图片

(4)思考

思考提问环节,现实中还有哪些对象存在继承性呢?举例说明父子的继承关系。

(5)思政

在工作和生活中的实践中,我们要学会继承的思想,“站在巨人的肩膀上前进”。

1.3. 继承的实现

(1)编写父类

不同类会有一些共同的特征和行为,将这些共同的特征和行为统一放到一个类中,这个类可以作为父类。

public class 父类{
    //公共的属性和方法
}

(2)编写子类,继承父类

声明子类继承父类,需要使用extends关键字,继承可以使得子类具有父类的属性和方法,还可以在子类中重新定义、追加属性和方法。

其语法格式如下所示:

public class 子类 extends 父类{
    //子类特有的属性和方法
}
  • 案例需求

定义一个人类(Person),定义成员变量姓名(String name)和年龄(int age),成员变量都是public修饰;定义成员方法eat( ),在其中输出“吃饭”,成员方法用public修饰。

定义一个学生类(Student),它继承Person类,定义成员变量学号(String stuCode),成员变量用public修饰。

编写程序,使用无参构造方法实现Student类的实例化,对成员变量姓名、年龄、学号进行访问,并调用eat( )和study( )方法。

  • Person类

public class Person {

    public String name;     //姓名
    public int age;         //年龄

    public void eat(){
        System.out.println("吃饭");
    }

}
  • Student类

public class Student extends Person {

    public String stuCode;  //学号

    public void study(){
        System.out.println("学习Java程序设计");
    }

}
  • 测试类

public class TestStudent {

    @Test
    public void test(){
        Student stu = new Student();
        //赋值
        stu.name = "张三";
        stu.age = 20;
        stu.stuCode = "20230101";
        //访问
        System.out.println(stu.name);
        System.out.println(stu.age);
        System.out.println(stu.stuCode);
        //访问方法
        stu.eat();
        stu.study();
    }

}

1.4. 练习

定义一个汽车类(Car),定义成员变量汽车品牌(String brand)、价格(double price),成员变量都是public修饰;定义成员方法drive( ),在其中输出“张三开着大众牌(brand值)汽车,价格是10(price值)万”,成员方法用public修饰。

定义一个电动汽车(ElectricCar),它继承Car类,定义成员变量电池容量(String batterySize),成员变量用public修饰;定义成员方法charge( ),在其中输出“给电动汽车充电”。

编写程序,使用无参构造方法实现ElectricCar类的实例化,对成员变量汽车品牌、价格、电池容量进行访问,调用drive( )和charge( )成员方法。

1.5. 思考

自定义一个父类,定义其成员变量(为子类抽取公有属性),成员变量都是public修饰;定义成员方法(为子类公有的方法),成员方法用public修饰。

自定义一个子类,它继承父类,定义子类特有的成员变量,成员变量用public修饰;定义子类成员方法(为子类特有)。

编写程序,使用无参构造方法实现子类的实例化,访问所有成员变量,并调用所有成员方法。

1.6. 继承的注意事项

(1)在Java中,类只支持单继承,不允许多继承。也就是说一个类只能有一个直接父类。

public class A{
}
public class B{
}
public class C extends A,B{ // C类不可以同时继承A类和B类
}  

(2)在Java中,多层继承也是可以的,即一个类的父类可以再继承另外的父类。例如,C类继承自B类,而B类又可以继承自类A,这时,C类也可称作A类的子类。

public class A{
}
public class B extends A{ // 类B继承类A,类B是类A的子类
}   
public class C extends B{ // 类C继承类B,类C是类B的子类,同时也是类A的子类
}

1.7. 方法的重写

(1)概念

在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。在子类中重写的方法需要和父类被重写的方法具有相同的方法名、参数列表以及返回值类型。

注意:子类重写父类方法时,不能使用比父类中被重写的方法更严格的访问权限。例如,父类中的方法是public权限,子类的方法就不能是private权限。如果子类在重写父类方法时定义的权限缩小,则在编译时将出现错误。

(2)案例

定义一个人类(Person),定义成员变量姓名(String name)和年龄(int age),成员变量都是private修饰,分别为这两个成员变量定义访问方法(getter)和修改方法(setter);定义成员方法hello( ),在其中输出“我的姓名是张三,我的年龄是20”,成员方法用public修饰。

定义一个学生类(Student),它继承Person类,定义成员变量班级(String className),成员变量用private修饰;重写父类成员方法hello( ),在其中输出“我的姓名是张三(name值),我的年龄是20(age值),我的班级是Java一班(className值)”,成员方法用public修饰。

编写程序,使用无参构造方法实现Student类的实例化,通过修改方法(setter)对成员变量赋值,调用访问方法(getter)输出变量值,并调用hello( )方法。

  • Person类

public class Person {

    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 hello(){
        System.out.println("我的名字是:" + this.name+"我的年龄是:" +this.age);
    }
}
  • Student类

public class Student extends Person{

    private String className;

    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }

    @Override
    public void hello() {
        super.hello();
        System.out.println("我的班级是:" + this.className);
    }
}
  • 测试类

public class TestStudent {

    @Test
    public void test(){
        //实例化对象(无参构造方法)
        Student stu = new Student();
        //成员变量赋值
        stu.setName("张三");
        stu.setAge(20);
        stu.setClassName("Java一班");
        //输出成员变量值
        System.out.println(stu.getName());
        System.out.println(stu.getAge());
        System.out.println(stu.getClassName());
        //成员方法调用
        stu.hello();
    }

}

1.8. super关键字

当子类重写父类的方法后,子类对象将无法访问父类中被子类重写过的方法。为了解决这个问题,Java提供了super关键字,使用super关键字可以在子类中访问父类的非私有方法、非私有属性以及构造方法。下面详细讲解super关键字的具体用法。

(1)使用super关键字访问或调用父类的非私属性或非私有方法,具体格式如下。

super.属性
super.方法(参数1,参数2…)

(2)使用super关键字调用父类中指定的构造方法,具体格式如下。

super(参数1,参数2…)

(3)super和this关键字的区别

super与this关键字的作用非常相似,都可以调用构造方法、方法和属性,但是两者之间还是有区别的,super与this的区别如下表所示。

区别点

super

this

访问属性

直接访问父类中的非私有属性

访问本类中的属性。如果本类中没有该属性,则从父类中继续查找

调用方法

直接调用父类中的非私有方法

调用本类中的方法。如果本类中没有该方法,则从父类中继续查找

调用构造方法

调用父类构造方法,必须放在子类构造方法的首行

调用本类构造方法,必须放在构造方法的首行

你可能感兴趣的:(Java程序设计,java,继承性)