JavaSE基础七:Java 面向对象三大特性之继承(构造方法、static 关键字、代码块、继承案例)、多态(多态实现、访问成员的特点、转型、多态案例)

Java 面向对象三大特性之继承、多态

上篇详细讲述了封装所需要的知识,下面辅以代码,对继承和多态进行详述。

继承详述

1、构造方法

构造方法:是 Java 中一种特殊类型的方法,用于初始化对象,在创建对象时被默认调用。

构造方法的分类:空参构造,有参构造

构造方法的特点:

  • 方法名与类名相同。
  • 方法声明上没有返回值类型这一项(连 void 也没有,void 表示这个方法不需要返回结果)。

注意事项:

  • 在一个类中,如果没写构造方法,系统会默认添加空参构造;如果写了构造方法,系统将不会再添加空参构造。
  • 如果只写了有参构造,系统不会默认添加空参构造,这时就无法使用空参构造。
  • 建议永远手动写出空参构造。

以学生类为例:

学生类成员变量:name、age

空参构造:

//方法名与类名相同
//没有返回值类型这一项
public Student() {
}

有参构造:

public Student(String name, int age) {
    this.name = name;
    this.age = age;
}

完整代码:

public class Student {
    private String name;
    private int age;

    //空参构造
    public Student() {
    }

    //有参构造
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

创建对象时,如果没有顺带传入数据,系统会默认调用空参构造,这时再想赋值,必须使用 set()、get() 方法;

如果顺带传入了数据,系统会调用有参构造,直接给对象的成员变量赋值。

2、static 关键字

static:静态

被 static 关键字修饰的方法或变量不需要依赖对象来访问,只要类加载了,就可以通过类名进行访问。

简单来说就是:方便在没有创建对象的情况下来进行调用(方法/变量)。

被 static 修饰的成员,在类的.class文件加载进方法区时,会被放入方法区中的静态区。

static 关键字的特点:

  • 随着类的加载而加载
  • 优先于对象存在
  • 被类的所有对象共享
  • 可以通过类名调用,也可以通过对象调用,建议通过类名调用

注意事项:

  • 在 static 修饰的方法中是没有 this 的,因为静态是随着类的加载而加载,this 是随着对象的创建而存在,静态比对象优先存在。
  • 静态方法只能访问静态的成员。

静态变量和成员变量的区别:

  • 所属不同。静态变量属于类,成员变量属于对象。
  • 内存中的位置不同。静态变量在方法区的静态区,成员变量在堆内存。
  • 出现的时间不同。静态变量随着类的加载而加载,成员变量随着对象的创建而存在。
  • 调用不同。静态变量可用类名或对象调用,成员变量只能用对象调用。
3、代码块

代码块:使用 {} 括起来的代码。

代码块的分类:普通代码块、构造代码块、静态代码块、同步代码块

普通代码块:方法的方法体。

构造代码块:类中方法外的代码块,在创建对象时被默认调用,每次创建都会调用,优先于构造方法执行。

静态代码块:使用 static 修饰的代码块,随着类的加载而加载,只会执行一次。

同步代码块:使用 synchronized 修饰的方法体,保证多线程下,对共享数据的读写是互斥的。

public class CodeBlock {
    //静态代码块
    static {
        System.out.println("静态代码块");
    }
    
    //构造代码块
    {
        System.out.println("构造代码块");
    }

    //普通代码块就是方法体
    public CodeBlock() {
        System.out.println("普通代码块");
    }
}

class Test03{
    public static void main(String[] args) {
        CodeBlock codeBlock = new CodeBlock();
    }
}

结果:

静态代码块
构造代码块
普通代码块

主方法进栈后,在创建 CodeBlock 对象前,要先加载 CodeBlock 类,静态代码块随着类的加载而加载,所以先输出:静态代码块,创建对象时,构造代码块优先于构造方法执行,输出:构造代码块,接着调用构造方法,输出:普通代码块。

4、继承

基于已有类派生出新类,已有类称为父类,派生类称为子类,二者的关系称为继承,用关键字 extends 表示。

格式:

class 父类{};
class 子类 extends 父类{};

继承的好处:

  • 提高了代码的复用性。
  • 提高了代码的维护性。
  • 让类与类之间产生了关系,是多态的前提。

继承的弊端:

  • 类与类之间的耦合性增强了。开发所遵循的逻辑应该是:高内聚,低耦合。

继承的特点:

  • Java 中只支持单继承,不支持多继承。也就是说,每个子类只能有一个父类。
  • Java 中支持多层继承。也就是说,父类可能是另一个类的子类。

继承的注意事项:

  • 子类只能继承父类非私有的成员。
  • 子类不能继承父类的构造方法,但是可以通过 super 关键字去访问父类的构造方法。
  • 不要为了部分功能去继承。

继承中成员变量的调用逻辑:

  • 当子类和父类的变量名没有重名时,按照变量名调用。

  • 当子类和父类的变量名有重名时,按照”就近原则“调用:

    • 在子类方法的内部范围寻找,找到优先调用。
    • 如果方法内部没有该变量,在子类的成员变量范围内寻找,找到调用。
    • 如果子类范围没有该变量,在父类中去寻找,找到调用。

this 和 super 的区别和使用:

this 代表本类的引用;super 代表父类存储空间的标识,可以理解为父类的引用。

this 和 super 的使用:

调用成员变量调用构造方法调用成员方法
thisthis.变量名this()this.方法名()
supersuper.变量名super()super.方法名()

继承中构造方法的关系:

子类中所有构造方法都会默认调用父类的空参构造,因为子类要继承父类中的数据,必须先完成父类的初始化。

实现原理:子类构造方法的第一条语句是隐藏的 super(),系统默认添加的。

注意:当父类没有空参构造时,子类应通过 super() 显示的调用父类的有参构造。

this()、super() 必须出现在构造方法的第一条语句上。

继承中方法的调用逻辑

当子类方法和父类方法没有重名时,按照方法名调用。

当子类方法和父类方法有重名时,先查找子类中有无调用的方法,有就优先调用,无再去调用父类中的方法。

方法重写:

子类中出现和父类方法名相同的方法,被称为重写,也叫覆盖。

当子类需要父类功能的同时,又想拥有自己独特的内容,就可以重写父类中的方法。这样既沿袭了父类的功能,又定义了子类独特的功能。

注意事项:

  • 父类中私有的方法不能被重写,因为子类根本无法继承父类的私有方法。
  • 子类重写父类的方法时,访问权限不能变低,最好一致。
  • 父类方法是静态方法,子类也必须重写成静态方法。

final 关键字

final:最终的意思,可以修饰类、变量、方法。

final 修饰的特点:

  • 修饰类时,该类不能被继承。
  • 修饰方法时,该方法不能被重写。
  • 修饰变量时,该变量变为常量,不能被重新赋值。
5、继承案例

创建人类:

public class Person {
    private String name;
    private int age;

    //空参构造
    public Person() {
    }

    //有参构造
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //set() get() 方法
    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 sleep(){
        System.out.println("任何人都需要睡觉");
    }
}

老师类继承人类:

//继承人类
class Teacher extends Person{
    //空参构造
    public Teacher() {
        //这里有隐藏的 super(); 语句,默认访问父类的空参构造。
    }
    
    //重写父类方法
    public void sleep() {
        System.out.println("各个人的睡眠时间不同");
    }
}

测试类:

class Test{
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        //继承来的 set() 方法
        teacher.setName("张三");
        teacher.setAge(21);

        //调用的是子类重写的 sleep() 方法
        teacher.sleep();
        System.out.println(teacher.getName());
        System.out.println(teacher.getAge());
    }
}

多态详述

1、多态实现

多态:同一对象的多种表现形式。

具体来说就是,一个引用变量到底会指向哪个类的实例,该实例发出的方法调用到底调用哪个类的方法,必须在运行期才能决定。

多态的具体实现:父类引用指向子类对象。

父类 对象名 = new 子类();
2、多态中成员的访问特点

成员变量:编译看左边,运行看左边。

构造方法:子类创建时会默认访问父类的构造方法,对父类进行初始化。

成员方法:编译看左边,运行看右边。

静态方法:编译看左边,运行看左边。

3、多态的利弊

利:继承提高了代码的维护性,多态提高了代码的扩展性。

弊:不能使用子类特有的功能。

4、多态中的转型

多态的转型分为两种:向上转型、向下转型。

向上转型:多态本身就是向上转型,子类对象使用父类类型接收。

向下转型:将父类类型对象转为子类引用。

子类类型 对象名 = (子类类型) 父类类型对象;

向下转型后,就可以解决多态不能使用子类特有功能这一问题。

5、多态案例

动物类:

public class Animal {
    //成员变量
    int age = 1;

    //空参构造
    public Animal() {
        System.out.println("Animal 类的构造方法");
    }

    //成员方法
    public void eat(){
        System.out.println("动物吃饭");
    }
}

猫类:

继承动物类

class Cat extends Animal{
    //同名变量
    int age = 2;
    
    //重写父类 eat() 方法
    public void eat() {
        System.out.println("猫吃猫粮");
    }
}

测试类:

class Test02{
    public static void main(String[] args) {
        //多态创建猫类,用动物类接收,会默认调用动物类的空参构造
        Animal animal = new Cat();

        //调用成员变量,编译运行看左边
        int age = animal.age;          //得到的是左边 Animal 类中的 age
        System.out.println(age);   	   //打印 1
        
        //调用成员方法,编译看左边,运行看右边
        animal.eat();		//调用的是 Cat 类的 eat() 方法

        //向下转型
        Cat cat1 = (Cat) animal;
        //向下转型后,就可以使用子类特有的功能
        int age1 = cat1.age;		//得到的就是 cat 类的 age
        System.out.println(age1);
    }
}

你可能会从天而降,也可能从林间降落,但最好的降落方式是,与我坠入爱河.

各位看官,面向对象三大特性结束咯,我们下篇见 (∩_∩)~~

                                                                                                                                                                                  -Czx.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值