【韩顺平Java笔记】第8章:面向对象编程(中级部分)【314-326】

314. 动态绑定机制


【注】属性没有动态绑定机制


虽然B类sum被注释掉了,但是其父类A类的sum方法没被注释掉,所以调用的是A类的sum方法,A类的sum方法中有个getI()方法,根据动态绑定机制,现在这个a引用的运行类型是B类,子类B里恰好也有getI()方法,所以调用getI()的时候先从子类B找,发现子类B有getI()方法,就调用子类B的getI()方法,子类B的getI()对应的返回的是B类的属性i,属性没有动态绑定机制,所以getI()返回20.

315. 多态数组

数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组
中,并调用每个对象
say 方法. 应用实例升级:如何调用子类特有的方法,比如
Teacher 有一个 teach , Student 有一个 study
怎么调用?

Person.java

package com.Marisa.ployarr_;

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

    public Person(String name, int age) {
        this.name = name;
        this.age = 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 String say(){
        return "name:" + name + "\t" + "age:" + age + "\t";
    }
}

Student.java

package com.Marisa.ployarr_;

public class Student extends Person{
    private double score;

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    //重写父类say方法

    @Override
    public String say() {
        return "学生:\t" + super.say() + "socre:" + score + "\t";
    }
}


Teacher.java

package com.Marisa.ployarr_;

public class Teacher extends Person{
    private double salary;

    public Teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
    //重写父类say方法

    @Override
    public String say() {
        return "老师:\t" + super.say() + "salary" + salary + "\t";
    }
}

PoloArray.java

package com.Marisa.ployarr_;

public class PoloArray {
    public static void main(String[] args) {
        Person[] persons = new Person[5];
        persons[0] = new Person("田所浩二", 24);
        persons[1] = new Student("德川", 26, 114514);
        persons[2] = new Student("我修院", 26, 114514);
        persons[3] = new Teacher("王爷", 114514, 114514);
        persons[4] = new Teacher("淳平", 114514, 114514);
        //循环遍历多态数组,调用say
        for (int i = 0; i < persons.length; i++) {
            //persons[i] 编译类型是Person,运行类型是根据实际情况有JVM判断
            System.out.println(persons[i].say());//动态绑定机制
        }

    }
}

运行结果:
name:田所浩二 age:24
学生: name:德川 age:26 socre:114514.0
学生: name:我修院 age:26 socre:114514.0
老师: name:王爷 age:114514 salary114514.0
老师: name:淳平 age:114514 salary114514.0

316. 多态数组2

为Student类和Teacher类加入特有方法
Student.java

package com.Marisa.ployarr_;

public class Student extends Person{
    private double score;

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    //重写父类say方法

    @Override
    public String say() {
        return "学生:\t" + super.say() + "socre:" + score + "\t";
    }

    public void study(){
        System.out.println("学生" + getName() + "正在嗯嘛啊");
    }
}


Teacher.java

package com.Marisa.ployarr_;

public class Teacher extends Person{
    private double salary;

    public Teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
    //重写父类say方法

    @Override
    public String say() {
        return "老师:\t" + super.say() + "salary" + salary + "\t";
    }
    //特有的方法
    public void teach(){
        System.out.println("老师" + getName() + "正在授课");
    }
}

PoloArray.java

package com.Marisa.ployarr_;

public class PoloArray {
    public static void main(String[] args) {
        Person[] persons = new Person[5];
        persons[0] = new Person("田所浩二", 24);
        persons[1] = new Student("德川", 26, 114514);
        persons[2] = new Student("我修院", 26, 114514);
        persons[3] = new Teacher("王爷", 114514, 114514);
        persons[4] = new Teacher("淳平", 114514, 114514);
        //循环遍历多态数组,调用say
        for (int i = 0; i < persons.length; i++) {
            //persons[i] 编译类型是Person,运行类型是根据实际情况有JVM判断
            System.out.println(persons[i].say());//动态绑定机制
            //调用特有方法
            //判断运行类型是不是Student
            if(persons[i] instanceof Student){
                ((Student)persons[i]).study();//向下转型
            }
            //判断是Teacher
            else if(persons[i] instanceof Teacher){
                ((Teacher)persons[i]).teach();
            }
        }

    }
}

运行结果:
name:田所浩二 age:24
学生: name:德川 age:26 socre:114514.0
学生德川正在嗯嘛啊
学生: name:我修院 age:26 socre:114514.0
学生我修院正在嗯嘛啊
老师: name:王爷 age:114514 salary114514.0
老师王爷正在授课
老师: name:淳平 age:114514 salary114514.0
老师淳平正在授课

317. 多态参数


Employee.java

package com.Marisa.polyparameter_;

public class Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

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

    //得到年工资
    public double getAnnual(){
        return 12 * salary;
    }
}

Manager.java

package com.Marisa.polyparameter_;

public class Manager extends Employee{
    private double bonus;

    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    //管理
    public void manage(){
        System.out.println("经理" + getName() + "正在管理");
    }
    //重写获取年薪方法
    //加奖金金金金金金
    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}

Worker.java

package com.Marisa.polyparameter_;

public class Worker extends Employee{
    public Worker(String name, double salary) {
        super(name, salary);
    }

    public void work(){
        System.out.println("普通员工" + getName() + "正在工作");
    }

    //普通员工没用其他收入,则直接调用父类
    @Override
    public double getAnnual() {
        return super.getAnnual();
    }
}

Test.java

package com.Marisa.polyparameter_;

public class Test {
    public static void main(String[] args){
        Worker w1 = new Worker("我修院", 114514);
        Manager m1 = new Manager("淳平", 114514, 1919);
        Test test = new Test();
        test.showmpAnnual(w1);
        test.showmpAnnual(m1);
        test.testWork(w1);
        test.testWork(m1);
    }
    public void showmpAnnual(Employee e){
        System.out.println(e.getAnnual());//动态绑定机制
    }
    //添加testWork方法,如果普通员工,调用work方法
    //如果是经理,调用manage方法
    public void testWork(Employee e){
        if(e instanceof Worker){
            ((Worker)e).work();//向下转型操作
        }else if(e instanceof  Manager){
            ((Manager)e).manage();
        }else{
            System.out.println("不做处理……");
        }
    }
}

运行结果:
1374168.0
1376087.0
普通员工我修院正在工作
经理淳平正在管理

318. ==运算符

package com.Marisa.object_;

public class Equals01 {
    public static void main(String[] args) {
        A a = new A();
        A b = a;
        A c = b;
        //==判断两个引用是否指向同一个对象
        System.out.println(a == c);
        System.out.println(a == b);
        B bobj = a;
        System.out.println(bobj == c);
    }
}
class B{

}
class A extends B{

}


运行结果
true
true
true

319. 查看JDK源码


查看方法看视频

320. 子类重写equals

String重写的equals


Object类的equals方法

Integer类的euqals方法


==只判断对象的地址是否相等

equals经过重写后判断的是值是否相等

321. equals课堂练习1

应用实例: 判断两个 Person 对象的内容是否相等,如果两个 Person 对象的各个属性值都一样,则返回 true,反之 false。

Person.java

package com.Marisa.equals_;

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

    public Person(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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 char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    //重写equals方法

    @Override
    public boolean equals(Object obj) {
        //如果两个是同一个引用(指向同一个地址,直接返回true)
        if(this == obj){
            return true;
        }
        //如果不是Person对象,返回false
        if(!(obj instanceof Person)){
            return false;
        }else{
            //是Person对象,判断值是否都相等
            Person temp = (Person)obj;//先将运行类型转换为Person
            return this.name.equals(temp.name) &&
                    this.age == temp.age &&
                    this.gender == temp.gender;
        }
    }
}

EqualsTest.java

package com.Marisa.equals_;

public class EqualsTest {
    public static void main(String[] args) {
        Person person1 = new Person("田所浩二", 24, '男');
        Person person2 = new Person("田所浩二", 24, '男');
        Person person3 = new Person("德川", 26, '男');
        System.out.println(person1.equals(person2));
        System.out.println(person1.equals(person3));
        System.out.println(person1.equals(person1));
        System.out.println(person1.equals(new String("123")));
    }
}

运行结果:
true
false
true
false

322. equals课堂练习2


输出:
false
true
false//没重写equals方法,对比的是地址
true
false

323. equals课堂练习3


输出:
true//表达式先转换到精度最大的类型即float,然后都是65.0,返回true(只有char、byte和short类型之间不能直接自动转换)
true//char转到精度更高的int,大写字母A的ASCII码是65
true//同上
false//不同的引用,地址不同
true//字符串内容相同
//不输出,类型不相同,编译器报错

324. hashCode

  1. 提高具有哈希结构的容器的效率!

  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!

  3. 两个引用,如果指向的是不同对象,则哈希值一般(有可能在很大的范围内有碰撞)是不一样的

  4. 哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址。

  5. 案例演示[HashCode_.java]: obj.hashCode() [测试:A obj1 = new A(); A obj2 = new A(); A obj3 = obj1]

  6. 后面在集合,中 hashCode 如果需要的话,也会重写, 在讲解集合时,老韩在说如何重写 hashCode()代码

325. toString

  1. 基本介绍
    默认返回:全类名+@+哈希值的十六进制,【查看 Object 的 toString 方法】
    子类往往重写 toString 方法,用于返回对象的属性信息
  2. 重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式.
    案例演示:Monster [name, job, sal] 案例: ToString_.java
  3. 当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster); 就会默认调用
    monster.toString()

326. finalize

  1. 当对象被回收时,系统自动调用该对象的 finalize 方法。子类可以重写该方法,做一些释放资源的操作【演示】
  2. 什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来
    销毁该对象,在销毁该对象前,会先调用 finalize 方法。
  3. 垃圾回收机制的调用,是由系统来决定(即有自己的 GC 算法), 也可以通过 System.gc() 主动触发垃圾回收机制,测
    试:Car [name]
    老韩提示: 我们在实际开发中,几乎不会运用 finalize , 所以更多就是为了应付面试.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔理沙偷走了BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值