JAVA学习2 抽象类和接口
多年以后,面对浩如烟海但是啥也看不懂的屎山代码,tcswuzb总是会想起他把抽象类和接口整理成wiki的那个晚上
抽象类和接口
抽象类 (abstract class)
抽象类是一种不能被实例化的类,通过abstract语法修饰
abstract不只可以修饰类,还可以修饰方法
抽象类:
public class 类名 {
}
抽象方法:
public abstract class 类名 {
//抽象方法只有方法签名,不能存在方法体,也就是不能有具体实现内容
public abstract 方法返回值类型 方法名() {
}
}
如果一个类中包含了抽象方法,那么该类必须是抽象类。反过来,抽象类不一定包含抽象方法。
对于抽象类,其实对比普通类多了个abstract关键字修饰外,类该有的成员变量、方法、构造器,抽象类都有。
抽象类不能实现,不能创建对象,只能作为父类被子类继承实现。子类继承抽象类,则必须实现继承抽象类中的全部抽象方法,否则子类也必须作为抽象类,无法被实例化并创建对象。
通过实现抽象类,在父类中定义未实现的虚拟方法,然后在子类中重写实现,从而更好地支持多态。 某种意义上讲,这也就是一种必备的现代程序设计模式。
public class Main {
public static void main(String[] args) {
Class myclass2 = new myClass();
myclass2.Method();
}
}
abstract class Class {
public abstract void Method();
}
class myClass extends Class {
public void Method() {
System.out.println("now is rewrite");
}
}
接口 (interface)
接口是一种抽象类型,其定义了一组方法的规范,但是不提供方法的具体实现
接口中的方法默认为抽象方法,接口中的变量默认是public static final的常量,接口不能通过new进行实例化,
相较于类继承,接口的优势在于一个类可以继承实现多个接口
public class 类名 implements 接口名1,接口名2,... {
}
详细代码如下:
// 定义一个接口
public interface Animal {
// 接口中的变量默认是public static final
int MAX_AGE = 100;
// 接口中的方法默认是public abstract
void eat();
void sleep();
}
// 实现接口的类
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping");
}
}
public interface Flyable {
void fly();
}
//继承实现多个接口
//鸟作为动物继承动物接口 同时鸟可以飞行继承飞行接口
public class Bird implements Animal, Flyable {
@Override
public void eat() {
System.out.println("Bird is eating");
}
@Override
public void sleep() {
System.out.println("Bird is sleeping");
}
@Override
public void fly() {
System.out.println("Bird is flying");
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog(); // 多态性
animal1.eat(); // 输出: Dog is eating
animal1.sleep(); // 输出: Dog is sleeping
Animal animal2 = new Bird(); // 多态性
animal2.eat(); // 输出: Bird is eating
animal2.sleep(); // 输出: Bird is sleeping
animal2.fly(); // 输出: Bird is flying
}
}
如果一个类在继承多个接口时,如果该类需要实例化,那么必须全部重写继承接口的全部方法,但是如果存在多个接口实现了同一个方法,那么必须要考虑实现冲突,否则会报错
主要解决方法有两个:
1.
//在实现类中重写该方法,明确指定使用哪个接口的默认实现。
interface InterfaceA {
default void method() {
System.out.println("InterfaceA method");
}
}
interface InterfaceB {
default void method() {
System.out.println("InterfaceB method");
}
}
// 解决冲突的方式
class MyClass implements InterfaceA, InterfaceB {
@Override
public void method() {
// 明确指定使用哪个接口的实现
InterfaceA.super.method(); // 使用InterfaceA的实现
// 或者
// InterfaceB.super.method(); // 使用InterfaceB的实现
}
}
2.
//当接口继承其他接口时,如果存在同名方法,会遵循接口继承的优先级规则。
interface Parent {
default void hello() {
System.out.println("Parent hello");
}
}
interface Child extends Parent {
default void hello() {
System.out.println("Child hello");
}
}
class Test implements Child, Parent {
// 这里会使用Child接口的hello方法,因为它是更具体的实现
}
抽象类和接口的共同点以及优势
共同点:
都不能直接实例化,必须通过子类继承实现
都是支持继承实现,都是对于对于多态性更好的支持
都是用于抽象设计,提供了抽象设计的规范和模板
抽象类优势
支持内部具体方法实现,从而减少代码量
可以有构造方法和成员变量
(实现方面)抽象类更适合做父类,更适合体现模板思想,实现代码复用性
接口优势
支持同时继承多个接口,具备更好的灵活性和扩展性
(实现方面)接口更适合做功能的解耦合,解耦合性更强更灵活

浙公网安备 33010602011771号