多态的概念比较简单,就是同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
public class Parent {
public void call() {
sout("im Parent") ;
}
}
// 1.有类继承或者接口实现
public class Son extends Parent {
// 2.子类要重写父类的方法
public void call() {
sout("im Son");
}
}
// 1.有类继承或者接口实现
public class Daughter extends Parent {
// 2.子类要重写父类的方法
public void call() {
sout("im Daughter");
}
}
public class Test {
public static void main(stringl] args) {
Parent p = new Son(); //3.父类的引用指向子类的对象
Parent p1 = new Daughter(); //3.父类的引用指向子类的对象
}
}
这样,就实现了多态,同样是Parent类的实例,p.call 调用的是Son类的实现、p1.call调用的是Daughter的实现。
???? 我认为,多态应该是一种运行期特性,Java中的重写是多态的体现。不过也有人提出重载是一种静态多态的想法,这个问题在StackOverflow等网站上有很多人讨论,但是并没有什么定论。我更加倾向于重载不是多态。
????方法的重载就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者重载方法。
public class HollisExample {
// 方法重载 - 第一个方法
public void display(int a) {
System.out.println("Got Integer data.");
}
// 方法重载 - 第二个方法
public void display(String b) {
System.out.println("Got String data.");
}
}
总之,方法的重载(Overloading)是指在同一个类中,可以有多个同名方法,只要它们的参数列表不同即可。方法的重载可以是参数个数的不同,也可以是参数类型的不同。
方法的重载使得程序可以根据不同的参数列表调用同名方法,增加了程序的灵活性和可读性。
public class Calculator {
// 加法方法,接受两个整数参数
public int add(int a, int b) {
return a + b;
}
// 加法方法,接受三个整数参数
public int add(int a, int b, int c) {
return a + b + c;
}
// 加法方法,接受两个浮点数参数
public double add(double a, double b) {
return a + b;
}
// 加法方法,接受三个浮点数参数
public double add(double a, double b, double c) {
return a + b + c;
}
public static void main(String[] args) {
Calculator calculator = new Calculator();
int sum1 = calculator.add(2, 3); // 调用第一个add方法(两个整数)
int sum2 = calculator.add(4, 5, 6); // 调用第二个add方法(三个整数)
double sum3 = calculator.add(2.5, 3.5); // 调用第三个add方法(两个浮点数)
double sum4 = calculator.add(4.5, 5.5, 6.5); // 调用第四个add方法(三个浮点数)
System.out.println("Sum1: " + sum1);
System.out.println("Sum2: " + sum2);
System.out.println("Sum3: " + sum3);
System.out.println("Sum4: " + sum4);
}
}
在这个例子中,创建了一个名为 Calculator 的类,其中包含了四个名为 add 的方法。这四个方法分别接受不同类型和数量的参数,实现了方法的重载。在 main 方法中,我们根据传入的参数类型和数量调用相应的 add 方法,演示了方法的重载在实际编程中的应用。
????重写指的是在Java的子类与父类中有两个名称、参数列表都相同方法的情况。由于他们具有相同的方法签名,所以子类中的新方法将覆盖父类的原有方法。
public class Parent {
// 父类的方法
public void display() {
System.out.println("Parent display()");
}
}
class Child extends Parent {
// 子类重写了父类的方法
@Override
public void display() {
System.out.println("Child display()");
}
}
public class Main {
public static void main(String[] args) {
Parent objl = new Parent();
obj1.display(); // 输出“Parent display()”
Parent obj2 = new Child();
obj2.display(); // 输出“Child display()”
}
}
总之,方法的重写(Overriding)是面向对象编程中的一个重要概念,指的是在子类中重新定义父类中的方法,以覆盖(override)父类中的原有方法。重写方法的目的是为了在子类中提供特定的行为,而不必修改父类的代码。
方法的重写需要满足以下规则:
1.方法名、参数列表必须与父类中的方法完全****相同。
2.返回类型可以是父类方法返回类型的子类型。
3.子类方法的访问级别不能低于父类方法的访问级别。
看一个代码实现方法的重写和多态的应用:
class Animal {
public void makeSound() {
System.out.println("The animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("The dog barks");
}
public void bark() {
System.out.println("The dog barks");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("The cat meows");
}
public void meow() {
System.out.println("The cat meows");
}
}
class Zoo {
public void playWithAnimal(Animal animal) {
animal.makeSound(); // 调用 Animal 类的方法
animal.bark(); // 调用 Dog 类的方法,因为 animal 实际上是 Dog 对象
animal.meow(); // 调用 Cat 类的方法,因为 animal 实际上是 Cat 对象
}
}
public class Main {
public static void main(String[] args) {
Zoo zoo = new Zoo();
Animal animal1 = new Dog();
Animal animal2 = new Cat();
zoo.playWithAnimal(animal1); // 输出 "The dog barks" 和 "The dog barks" 和 "The dog barks"
zoo.playWithAnimal(animal2); // 输出 "The cat meows" 和 "The cat meows" 和 "The cat meows"
}
}
在这个例子中,定义了一个 Animal 类,两个子类 Dog 和 Cat,以及一个 Zoo 类。Dog 类和 Cat 类分别重写了 makeSound 方法,并且添加了各自特有的方法 bark 和 meow。在 Zoo 类的 playWithAnimal 方法中,我们传入了一个 Animal 类型的参数。由于多态的存在,这个参数实际上可以是一个 Dog 对象或一个 Cat 对象。在方法内部,我们调用了 animal 的 makeSound 方法(实际上是调用子类的方法),以及子类特有的方法 bark 和 meow。因此,根据传入的参数类型,我们可以得到不同的输出结果。这个例子展示了方法的重写和多态的应用,使得程序更加灵活和可扩展。
1、重载是一个编译期概念、重写是一个运行期概念。
2、重载遵循所谓 “编译期绑定” , 即在编译时根据参数变量的类型判定应该调用哪一个方法。
3、重写遵循所谓 “运行期绑定” , 即在运行的时候,根据引用变量所指向的实际对象的类型来调用方法。