Java面型对象-细节篇2(动态绑定,多态应用,系统方法源码)

动态绑定机制(🚩🚩🚩非常重要)

!!!

  1. 调用方法时会和该对象的运行类型(内存地址)绑定
  2. 调用属性是不发生绑定,即为,在哪声明,在哪调用
public class Dynamicbinding{
    public static void main(String[] args){
        A a=new B();
        //正常情况,方法调用看运行类型即B;
        a.sum();//40
        a.sum1();//30
        //若B类sum()被注销
         a.sum();
        /*30;此时A类的sum中的getI()发生动态绑定。即为getI()会绑定为运				行类型;即为B下的getI();若没有,遵循向上查找*/
    }
}
class A{
    public int i=10;
    public int sum(){
        return getI()+10;
    }
    public int getI(){
        return i;
    }
    public int sum1(){
        return getI()+20;
    }
}
class B  extends A{
     public int i=20;
   /* public int sum(){
        return getI()+20;
    }*/
    public int getI(){
        return i;
    }
    public int sum1(){
        return getI()+10;
    }
}

多态的应用

1.多态数组

数组定义类型为父类类型,数组元素为子类类型

语法:

	 Person[] arr=new Person[3];
	 arr[0]=new Student("jack",21,151);
     arr[1]=new Student("luss",20,125);
     arr[2]=new Teacher("tom",32,23111);		

问题:

  • 访问子类共有方法

     for (int i = 0; i <arr.length ; i++) {
                arr[i].say();
            }
    
  • 访问子类特有方法(使用instanceOf判断元素运行类型,然后向下转型)

     for (int i = 0; i <arr.length ; i++) {
                arr[i].say();
         if(arr[i] instanceOf Student){
             ((Student)arr[i]).learn();//判断运行类型为学生,则调用学习方法
            }else if(arr[i] insatnceOf Teacher){
             ((Teacher)arr[i]).teach();//判断运行类型为老师,则调用教学方法
         }
     }
    

2.多态参数

即把上述访问子类特有方法封装成方法,在main栈调用

public class Poly_par{
public static void main(String[] args){
	Person[] arr=new Person[1];
    arr[0]=new Student("zhansan",21,151);
    (new Poly_par()).show();
}
    public void show(Person[] arr){//即为多态参数
        for (int i = 0; i <arr.length ; i++) {
            arr[i].say();
     if(arr[i] instanceOf Student){
         ((Student)arr[i]).learn();//判断运行类型为学生,则调用学习方法
        }else if(arr[i] insatnceOf Teacher){
         ((Teacher)arr[i]).teach();//判断运行类型为老师,则调用教学方法
     }
 }
    }
}


系统方法

1.比较运算符 ==

  • 🚩基本类型比较:
  • 🚩引用类型比较:地址

2.equals()方法

  • 由于是Object类中的方法,只能比较引用类型

  • 一般默认比较地址是否相等,通常子类会重写equals方法(如:字符串比较;会变成两个串的值比较)

    //jdk源码 String 重写equals方法
    public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])//⚡ 这里即为值比较
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
    

思考

String s1=new String("og80");
String s2=new String("og80");
s1==s2//false,此时比较的是两个地址是否相同
 s1.equals(s2)//true,⚡此时比较字符串的值是否相等

自定义重写equals

  1. 要求两个对象属性一致,返回true;

    如:Per p=new Per("name",21); Per p1=new Per("name",21);

    若不重写,上述为false

    //重写equals
    public class Override_equals{
        
        public static void main(String[] args){
            Per p=new Per("name",21);
            Per p2=new Per("name",21);
            p.equals(p2);//此时为true
        }
    }
    class Per{
        public int age;
        public String name;
        poublic Per(String name,int age){
            this.name=name;
            this.age=age;
        }
        public boolean equals(Object obj){
            if(this==obj){
                return true;
            }
            if(obj instanceof Per){
                Per p=(Per)obj;
                return this.name.equals(p.name) && this.age.equals(p.age);
            }
            return false;
        }
    }
    

3.haspCode()方法

作用:

  1. 提高具有哈希结构的容器效率
  2. 两个引用如果指向同一个对象,haspCode值一定相同
  3. haspCode是由jvm虚拟机地址换算而来,不等于地址值;
  4. 后续学习集合时,会重写haspCode()

4.toString()方法

介绍:

  1. 默认返回:全类名+@+哈希值的十六进制(全类名即为包名加类名)
  2. 重写toString()方法
  3. 直接输出对象时会默认调用toString()方法

toString()的jdk源码:

 public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

toString()方法重写

class Tos{
    public String name;
    public int age;

    @Override
    public String toString() {//输出对象属性;也可自定义
        return "Tos{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

5.finalize()方法

  1. 当对象被回收时,系统自动调用该方法,子类可重写
  2. 何时对象被回收:当某个对象没有任何引用时,jvm把该对象作为垃圾进行销毁;销毁之前调用finalize()方法
  3. 垃圾回收机制有系统决定,也可通过System.gc()主动触发
posted @   Chair-0u98  阅读(21)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示