Java重写与重载

 以下是翁恺老师的示例代码的一部分:

package dome;

public class CD extends Item{
    private String artist;
    private int numofTracks;
//    private int playingTime;
//    private boolean gotIt=false;
//    private String comment;

    public CD(String title, String artist, int numofTracks, int playingTime, String comment) {
        super(title,playingTime,false,comment);
//        this.title = title;
        this.artist = artist;
        this.numofTracks = numofTracks;
//        this.playingTime = playingTime;
//        this.comment = comment;
    }

    @Override
    public String toString() {
        return "CD{" +
                "artist='" + artist + '\'' +
                ", numofTracks=" + numofTracks +
                "} " + super.toString();
    }

    @Override    
    public boolean equals(Object obj) {   
    //public boolean equals(CD obj)  不加@Wverride  也可以成功运行,但这并不是重写Object类的equals方法,而是重载(overload)了一个新的方法
        CD cc=(CD)obj;  
        return artist.equals(cc.artist); 
    }

    public static void main(String[] args) {
        CD cd=new CD("a","b",2,2,"...");
        CD cd1=new CD("a","b",2,2,"...");
        System.out.println(cd.equals(cd1));
//        cd.print();
//        String s="aa"+cd;
//        System.out.println(s);
    }


    public void print() {
        System.out.print("CD:");
        super.print();
        System.out.println(":"+artist);
//        System.out.println("CD"+":"+title+":"+artist);
    }
}

分析下面这段代码:

重写

    @Override     
    public boolean equals(Object obj) {   
        CD cc=(CD)obj;  
        return artist.equals(cc.artist);  
    }
  1. @Override:
    @Override表示重写 注解使得 Java 编译器可以执行一个安全检查。如果你标注了一个方法为 @Override,但这个方法实际上并没有重写任何超类中的方法,编译器将报错。
  2. public boolean equals(Object obj) {...}:
    通常要在两个对象上调用此方法,如cd1.equals(cd2)
  3. CD cc=(CD)obj;:
    将传入的Object类型的对象强制转换为CD类型
  4. return artist.equals(cc.artist); :
    this.artist指的是cd1.artist,cc.artist指的是cd2.artist
  5. 重写:
    Java中,equals()方法用于比较两个对象是否等效。在这里CD类中重写equals()方法是为了定义CD对象之间的等价性。

方法的重写是基于类层次结构的

  1. 如果子类重写了父类的方法,当通过子类的实例调用该方法时,将调用子类的重写版本。
  2. 如果其他子类没有重写该方法,当通过这些子类的实例调用该方法时,将调用父类的版本。
class Item {
    public void print() {
        System.out.println("Item print");
    }
}

class CD extends Item {
    @Override
    public void print() {
        System.out.println("CD print");
    }
}

class DVD extends Item {
    // DVD 没有重写 print 方法
}
public class Main {
    public static void main(String[] args) {
        Item item = new Item();
        CD cd = new CD();
        DVD dvd = new DVD();

        item.print(); // 输出: Item print
        cd.print();   // 输出: CD print
        dvd.print();  // 输出: Item print
    }
}

重载:

public boolean equals(CD obj){
    return artist.equals(obj.artist);
}

区别:

  • 重写 vs 重载

    • 重写:方法签名(包括方法名、参数类型和顺序)必须完全匹配父类的方法。目的是在子类中提供父类方法的具体实现。
    • 重载:方法名相同但参数列表不同。目的是在同一个类中提供不同参数列表的同名方法。
  • Object 类的 equals 方法签名Object 类的 equals 方法签名是 public boolean equals(Object obj)。如果你定义 public boolean equals(CD obj),它并没有重写 Object 类的 equals 方法,因为参数类型不同。这个方法是一个新的方法,只是与 equals 名字相同,但并不会覆盖 Object 类的 equals 方法。

  • 调用行为

    • 如果你在 main 方法中调用 cd1.equals(cd2),而没有重写 Object 类的 equals 方法(即 public boolean equals(Object obj)),它将调用 Object 类的默认实现,而不是你定义的 public boolean equals(CD obj) 方法。
    • 为了使 equals 方法在所有场景下都能正常工作,特别是在集合类(如 HashSetHashMap)等需要比较对象相等性的地方,你必须重写 Object 类的 equals 方法。

方法调用解析

在Java中,方法的调用是基于静态类型解析的(也就是编译时的类型)。cd1.equals(cd2) 会首先查找最匹配的方法签名。如果存在一个更具体的重载版本(例如 equals(CD obj)),编译器会选择这个版本。

为什么调用了重载的方法

当你调用 cd1.equals(cd2) 时,cd1cd2 的静态类型是 CD,编译器会选择与 CD 类型最匹配的方法签名。如果存在一个 equals(CD obj) 方法,编译器会选择这个重载方法。

结论

  • 当使用重载方法时,编译器会选择最具体匹配的方法签名。因此,在你定义了 equals(CD obj) 方法并调用 cd1.equals(cd2) 时,编译器会选择这个重载的方法。
  • 为了确保所有情况下都能正确比较对象(尤其是在集合类中使用时),你需要重写 Object 类的 equals 方法,签名为 public boolean equals(Object obj)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值