Day07

3 阅读6分钟

面向对象高级

1.继承

介绍:让类与类之间产生关系(子父类关系),子类可以直接使用父类中非私有的成员

格式:

public class zi extends FU{}
package com.itheima.mextends;

public class ExtendsDemo1 {
    public static void main(String[] args) {
        Coder c = new Coder();
        c.setName("张三");
        c.setAge(23);
        c.setSalary(12000);

        System.out.println(c.getName() + "---" + c.getAge() + "---" + c.getSalary());
    }
}

class Employee {

    private String name;
    private int age;
    private double salary;

    public void work() {
        System.out.println("员工工作");
    }

    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 double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

class Coder extends Employee {

}

class Manager extends Employee {

}

1.1好处与弊端

  • 好处:提高了代码的复用性,维护性
  • 弊端:类和类之间的耦合性增强了

1.2继承中成员变量的访问特点

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

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

1.3成员变量(包括静态变量)

  • 子类和父类重名变量:互不影响
  • 访问规则:等号左边是谁,就用谁的变量
  • 编译、运行都看父类(引用类型)
class Fu {
    int num = 10;
}
class Zi extends Fu {
    int num = 20;
}

// 测试
Fu f = new Zi();
System.out.println(f.num); // 输出 10(用的父类变量)

1.4 成员方法(非静态)

  • 子类重写父类方法:执行子类
  • 访问规则:编译看父类,运行看子类
  • 编译检查父类有没有,运行执行子类(真实对象)
class Fu {
    void show() { System.out.println("父类"); }
}
class Zi extends Fu {
    void show() { System.out.println("子类"); } // 重写
}

// 测试
Fu f = new Zi();
f.show(); // 输出 子类

2.方法的重写

介绍

在继承体系中,子类可以继承到父类的方法

但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改

这就需要采用方法的重写,方法重写又称方法覆盖

要求

子类重写父类方法,需要保证方法声明完全一致(方法名,参数,返回值类型需要保持一致)

package com.itheima.mextends;

public class ExtendsDemo3 {
    /*
        方法重写的使用场景:
            子类继承了父类的方法, 但是子类不想原封不动的继承父类的方法逻辑
            想要修改或者是增强, 就可以重写父类方法.

        方法重载(Overload): 在同一个类中, 方法名相同, 参数不同, 与返回值无关
                                参数不同: 个数不同, 类型不同, 顺序不同.

        方法重写(Override): 在子父类中, 出现了方法声明完全一致的方法
                                (方法名, 参数, 返回值都需要和父类保持一致)

     */
    public static void main(String[] args) {
        Son s = new Son();
        s.love();
    }
}

class Father {
    void love() {
        System.out.println("送花");
        System.out.println("送自行车");
        System.out.println("送冰箱");
    }
}

class Son extends Father {
    @Override       // Override注解: 校验当前方法, 是否是重写的方法
    public void love() {
        super.love();
        System.out.println("送口红");
        System.out.println("送包");
    }
}

注意事项:

1.父类中的私有方法不能被重写

2.子类重写父类方法时,访问权限必须大于等于父类,大多数情况都是public

3.继承的特点

继承:java支持单继承,不支持多继承,但支持多层继承

4.继承成员访问特点-构造方法

1.构造方法不能继承,子类需要手动编写自己的构造方法

原因:构造方法要求方法名与类名相同,如果继承了父类的构造方法,就无法与类名相同了

2.子类在初始化之前,需要先完成父类的初始化

3.因为子类在初始化的时候,很有可能要用到父类中的数据,如果父类没有提前完成初始化,子类将无法使用父类数据

4.构造方法,所以子类只要有办法调用到父类的构造方法,就能完成父类初始化

5.this和super关键字

this:代表本类对象的引用

super:代表父类存储空间的标识

super(...)`:调用父类的构造方法

子类构造方法默认会自动调用父类的无参构造super()),如果父类只有有参构造,必须手动用

6.final关键字

final 关键字是最终的意思,可以修饰(方法,类,变量)

修饰方法:表明该方法是最终方法,不能被重写

修饰类:表明该类是最终类,不能被继承

修饰变量:表明该变量是常量,不能再次被赋值

inal 修饰的变量就变成了常量,常量的命名规范建议所有final修饰的如下

  1. 如果是一个单词: 所有字母大写 MAX
  2. 如果是多个单词: 所有字母大写, 中间使用_分割 MAX_VALUE

7.接口

7.1接口的定义格式

1.接口用关键字interface来定义

public interface 接口名{}

2.接口不能实例化

3.接口和类之间时实现关系,通过implements关键字表示

4.接口的子类要么重写接口中的所有抽象方法,要么时抽象类

7.2接口中的成员特点

1.成员变量:

只能是常量 默认修饰符:public static final

2.构造方法:

没有

3.成员方法:

只能是抽象方法

默认修饰符:public abstract

7.3类和接口的各种关系

1.类和类的关系:

继承关系,只能单继承,但是可以多层继承

2.类和接口的关系:

实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

3.接口和接口的关系:

继承关系,可以单继承,也可以多继承

(接口允许多实现,因为内部的方法都是抽象的,抽象方法不存在方法体,所以不会产生逻辑冲突)

8.多态

同一个行为具有多个不同表现形式或形态的能力

8.1多态的前提条件

1.有继承 / 实现关系

2.有方法重写

3.有父类引用指向子类对象

8.2多态的成员访问特点

成员变量:编码看左边(父类),执行看左边(父类)

成员方法:编码看左边(父类),执行看右边(子类)

public class PolymorphismDemo1 {
    /*
        成员变量: 编译看左边(父类), 运行看左边(父类)
                因为是父类的引用, 所以访问存在局限性, 只能访问super空间中的数据.
    */
    public static void main(String[] args) {
        Fu f = new Zi();
        System.out.println(f.num);          // 10
    }
}
class Fu {
    int num = 10;
}

class Zi extends Fu {
    int num = 20;
}

9.object类的equals方法

package com.itheima.object;

import com.itheima.pojo.Student;

import java.util.Random;

public class ObjectMethodDemo {
    /*
        == 号
            1. 基本数据类型: 比较数据值
            2. 引用数据类型: 比较地址值

        Object类中equals方法默认也是比较地址值
            public boolean equals(Object obj) {
                return (this == obj);
            }
        结论: 推荐重写equals方法, 自己定制比较规则.
     */
    public static void main(String[] args) {
        Student stu1 = new Student("张三", 23);
        Student stu2 = new Student("张三", 23);

        System.out.println(stu1.equals(stu2));
        System.out.println(stu1.equals(new Random()));
    }
}

10.代码块

在Java类下,使用 { } 括起来的代码被称为代码块

分类:

1.局部代码块

2.构造代码块

3.静态代码块

4.同步代码块