在Java中,方法重写是指子类覆盖(重写)其父类中具有相同名称、参数列表和返回类型的方法的过程。子类通过重新是写父类的方法,可以对该方法的实现进行更改或添加新的功能。当子类调用该方法时,将优先执行子类的方法,而不是父类的方法。
为了实现方法重写,子类中的方法必须具有与父类中被重写的方法相同的方法签名(即方法名称、参数类型和返回类型)。此外,子类中的方法访问修饰符必须与父类中的方法相同或更为宽松,例如,如果父类中的方法是public,则子类中的方法可以是public或protected,但是不能是private。
方法重写可以帮助子类实现特定的需求,同时也遵循了面向对象编程的多态性原则。这使得程序可以更加灵活和可扩展,因为子类可以根据需要重写或增加父类中的方法,从而实现更复杂的逻辑。
重写时,可以用super.方法的方式来保留父类的方法,构造方法不能被重写。
Java中方法重写(Method Overriding)规则如下:
1.方法名称必须相同:子类中的方法必须与父类中的方法同名,否则就是一个新的方法。
2.参数列表必须相同:子类中的方法的参数列表必须与父类中的方法的参数列表完全一致,包括参数的类型、顺序和数量。
3.返回值必须相同或是其子类:子类中的方法的返回值必须与父类中的方法的返回值完全一致或是其子类。
4. 访问权限不能低于父类方方法的访问权限:子类中的方法的访问权限不能低于父类中的方法的访问权限。例如,父亲中方法是public,则子类中的方法可以是public、protected或default,但不能是private。父类的方法是protected,子类重写的方法不能是private。
5.抛出的异常不能超过父类方法抛出的异常。
6. 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法。
7.子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
8.父类的私有方法不能被子类覆盖。
Object类
1. Object类是所有类的父亲。
2. Object类被子类经常重写的方法:
a. toString():返回当前对象本身的有关信息,按字符串对象返回。
b. equals(): 比较两个对象是否为同一个对象,是则返回true。
c. hashCode(): 返回该对象哈希代码值。
d. getClass(): 获取当前对象所属的类信息,返回Class对象。
Object类是所有类的基类,在Object类中有一个equals()方法,用于比较两个对象是否相等。'=='运算符用于比较两个对象的引用是否相等。即他们在内存中地址相同,则'=='运算符返回true,否则返回false。
Object类的equals()方法,当我们说object类的equals()方法与==运算符没区别时,实际上是指默认情况下,equals()方法会调用 == 运算符来比较两个对象的引用是否相等。因此,如果没有在自定义类中重写'equals()'方法,那么默认情况下,'equals'方法与'=='运算符的结果是一样的。
比较两个对象是否为同一个对象,是则返回true。操作符==
简单数据类型,直接比较值。如 1 == 2
引用类型,比较两者是否为同一对象。
然而,重写'equals()'方法可以改变默认的相等比较行为,使其比较对象的内容而不是引用。所以当我们需要比较两个对象的内容时,应该重写'equals()'方法来实现自定义的比较逻辑。
Object类的toString()方法,它返回一个字符串,该字符串描述了该对象的内容。当我们将一个对象传递给System.out.println()方法时,Java会自动调用该对象的toString()方法,并将其返回的字符串打印到控制台上。
默认情况下,object类中的toString()方法返回一个字符串,其中包含对象的类名和对象的哈希码值,格式为 getClass().getName() + '@' + Integer.toHexString(hashCode())
。但是,这个默认的实现不会提供任何有关对象内容的信息。因此,我们通常需要在自己的类中重写‘toString()’方法,以便放回一个有实际意义的字符串。
同一种事物,由于条件不同,产生的结果也不同。
多态:同一个引用类型,使用不同的实例而执行不同操作。
多态的作用:频繁修改代码,代码可扩展性、可维护性差,使用多态优化。
在 Java 中,通过多态特性创建的对象可以被视为父类类型或接口类型的对象,因此,使用父类或接口类型的引用变量来引用子类对象时,只能访问父类或接口中定义的属性和方法,而不能直接访问子类特有的属性和方法。
因此,在代码 Animal animal = new Cat();
中,虽然 animal
变量引用的实际对象是 Cat
类型的对象,但在使用 animal
变量时,只能访问 Animal
类型中定义的方法或属性,而不能直接访问 Cat
类型中特有的方法或属性。
如果需要调用 Cat
类型中特有的方法,需要将 animal
变量转换为 Cat
类型,然后才能调用 Cat
类型中的方法,例如:
Animal animal = new Cat();
// ...
if (animal instanceof Cat) {
Cat cat = (Cat) animal; // 将 animal 强制转换为 Cat 类型
cat.specialMethod(); // 调用 Cat 类型中的特有方法
}
需要注意的是,在进行类型转换时,应该先使用 instanceof
运算符检查对象类型,以避免类型转换异常。
方法重写是实现多态的基础,当我们调用子类对象的该方法时,实际上会调用子类中的方法,而不是父类中的方法。这种情况下,子类中的方法覆盖了父类中的同名方法,称为方法重写。方法重写实现了多态的一种形式,因为在运行时,程序会根据对象的实际类型来决定调用哪个方法。。
方法重写的规则:
方法名相同,参数列表相同,返回值类型相同或者是其子类。访问权限不能严于父类,父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法。子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super),父类的私有方法不能被子类覆盖,不能抛出比父类方法更多的异常。
多态向上转型:父类的引用指向子类的对象,自动进行类型转换。
<父类型><引用变量名> = new <子类型>();
使用父类作为方法的形参,是Java中实现和使用多态的主要方式。
多态向下转型:将一个指向子类对象的父类引用赋给一个子类的引用,即父类类型转换为子类类型。需强制类型转换。例:Dog dog(子类的引用) = (Dog)pet(指向子类对象的父类引用),将pet转换为Dog类型。dog.catchingFlyDisc();//执行Dog特有的方法。
<子类型><引用变量名> = (<子类型>)<父类型的引用变量>;
使用父类作为方法的返回值,也是Java中实现和使用多态的主要方式。
Java中提供了instanceof运算符来进行类型的判断,使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系。
Java多态性的主要作用包括:
-
提高代码的灵活性和可扩展性:通过多态性,可以编写更加通用和灵活的代码,因为代码可以与多个不同的对象交互,而不需要知道对象的具体类型。
-
促进代码的重用:通过多态性,可以将代码的通用部分提取出来,形成父类或接口,然后让不同的子类或实现类继承或实现这些通用部分,从而避免代码的重复。
-
简化代码的维护:通过多态性,可以将代码的通用部分放在一个父类或接口中,从而可以更方便地对代码进行维护和修改,而不会影响到整个代码库。