1、方法重载和重写的区别。
方法重载(Overloading)和方法重写(Overriding)是Java中多态性的两个重要方面,但它们有着本质的区别:
方法重载(Overloading)
定义:方法重载是指在同一类中,可以有多个同名的方法,但这些方法的参数列表必须不同(参数的数量、类型或顺序不同)。方法的返回类型不影响重载。
作用:方法重载提供了在同一个类中使用相同名称但具有不同功能的方法的能力,这可以提高代码的可读性和简洁性。
编译期绑定:方法重载的决策是在编译时完成的,根据传递给方法的参数类型和数量,编译器会确定调用哪个方法。
示例:
public class Example {
public void method(int a) {
// ...
}
public void method(double a) {
// ...
}
public void method(int a, String b) {
// ...
}
}
方法重写(Overriding)
定义:方法重写发生在继承的上下文中。当子类提供与父类同名、相同参数列表和相同返回类型的方法时,就发生了方法重写。子类的方法必须使用@Override注解标记(虽然这不是强制的,但推荐使用以防止错误)。
作用:方法重写允许子类改变父类方法的行为,或者提供更具体的实现,这有助于实现多态性。
运行期绑定:方法重写的决策是在运行时完成的,即根据对象的实际类型来决定调用哪个方法。这就是动态绑定或晚绑定。
示例:
public class Parent {
public void method() {
System.out.println("Parent's method");
}
}
public class Child extends Parent {
@Override
public void method() {
System.out.println("Child's method");
}
}
2、抽象类与接口的区别。
在Java中,抽象类(abstract class)和接口(interface)都是用来实现抽象和多态的重要工具,但它们之间存在一些关键的区别:
抽象类
定义:抽象类是使用abstract关键字定义的类,它可以包含抽象方法(没有实现的方法)和具体方法(有实现的方法),以及成员变量。
继承:一个类只能继承一个抽象类。Java不支持多重继承,但在Java 8及以后的版本中,抽象类可以实现多个接口,从而实现某种程度上的多重继承。
实例化:抽象类不能直接实例化,但是可以声明抽象类的引用变量,指向其实现的子类的实例。
方法实现:抽象类可以有默认的实现,即非抽象方法,子类可以直接使用这些方法,或者覆盖它们以提供不同的实现。
成员变量:抽象类可以有实例变量,这些变量可以被子类继承和使用。
构造函数:抽象类可以有构造函数,这些构造函数可以在子类中使用。
接口
定义:接口是使用interface关键字定义的,它只包含抽象方法(在Java 8以前)和常量(默认是public static final)。从Java 8开始,接口可以有默认方法(使用default关键字)和静态方法(使用static关键字)。
实现:一个类可以实现多个接口,这提供了多重继承的能力。
实例化:接口不能实例化,也不能声明接口的实例变量。但是,可以声明接口类型的引用变量,指向实现了该接口的类的实例。
方法实现:接口中的方法默认是抽象的,没有实现。但从Java 8开始,接口可以有默认方法和静态方法,这些方法提供了默认实现。
成员变量:接口可以有常量,但不能有实例变量。所有的成员变量默认都是public static final。
构造函数:接口不能有构造函数,因为它们不能被实例化。
总结
抽象类更适用于定义一个基础的类骨架,包括共享的行为和状态,而接口更适用于定义一组行为规范。
抽象类和接口都可以用于实现多态,但是它们在实现机制和使用场景上有所不同。
抽象类可以包含构造函数、实例变量和具体方法,而接口不能包含这些特性。
一个类可以实现多个接口,但只能继承一个抽象类。