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

-  
提高具有哈希结构的容器的效率!
 -  
两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
 -  
两个引用,如果指向的是不同对象,则哈希值一般(有可能在很大的范围内有碰撞)是不一样的
 -  
哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址。
 -  
案例演示[HashCode_.java]: obj.hashCode() [测试:A obj1 = new A(); A obj2 = new A(); A obj3 = obj1]


 -  
后面在集合,中 hashCode 如果需要的话,也会重写, 在讲解集合时,老韩在说如何重写 hashCode()代码
 
325. toString
- 基本介绍
默认返回:全类名+@+哈希值的十六进制,【查看 Object 的 toString 方法】
子类往往重写 toString 方法,用于返回对象的属性信息 - 重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式.
案例演示:Monster [name, job, sal] 案例: ToString_.java - 当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster); 就会默认调用
monster.toString()

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

 



















