java 第四章 面向对象(下)(萌新必看基础概念详解)

4.1 类的继承

4.1.1什么是继承

在Java中,继承是一种使一个类(称为子类)可以使用另一个类(称为父类或超类)的属性和方法的机制。当一个类继承另一个类时,子类将自动获得父类的公有和受保护的属性和方法,从而可以通过这些属性和方法来实现自己的功能。在Java中,使用关键字"extends"来实现继承。

下面是一个简单的Java继承的例子:

class Animal {
    String name;
    int age;

    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println("Dog is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "Lucky";
        dog.age = 3;
        dog.eat(); // 继承自Animal类
        dog.bark(); // 自己添加的方法
    }
}

在这个例子中,Dog类继承了Animal类,获得了name、age和eat()方法。然后,Dog类添加了自己的bark()方法。主方法创建了一个Dog对象,并调用了它从Animal类继承来的eat()方法和自己添加的bark()方法。

4.1.2如何实现继承

在类的继承中,需要注意以下几个问题:

父类和子类的访问权限:子类只能访问父类中public和protected修饰的成员变量和方法,而private修饰的成员变量和方法只能在父类中被访问和使用。此外,子类可以访问父类中的默认访问权限(即没有访问修饰符)的成员变量和方法,但是只有在同一个包中才能访问。

子类重写(override)父类的方法:子类可以重写父类的方法,并且可以覆盖父类中的方法实现,以满足自己的需求。在子类中重写父类的方法时,必须保证方法名、参数列表和返回值类型都相同。另外,如果父类中某个方法被声明为final,则该方法不能被子类重写。

super关键字的使用:在子类中调用父类中的方法或构造函数时,可以使用super关键字来实现。使用super关键字可以让子类访问到父类中的属性和方法,同时避免了命名冲突的问题。

多重继承和接口:Java中不支持多重继承,即一个子类只能有一个直接的父类。但是,一个类可以实现多个接口,并从多个接口中获得属性和方法。在实现多个接口时,需要保证每个接口中的方法名和参数列表都不相同。

总之,在类的继承中,需要考虑访问权限、重写方法、super关键字的使用以及多重继承和接口等问题,才能更好地实现代码的复用和扩展性。
继承的传递性
ava继承具有传递性,即如果类A继承自类B,而类B又继承自类C,则类A将隐含地获得类B和类C中所有的属性和方法。下面是一个简单的Java继承的例子:

class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Mammal extends Animal {
    public void run() {
        System.out.println("Mammal is running");
    }
}

class Dog extends Mammal {
    public void bark() {
        System.out.println("Dog is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); // 继承自Animal类
        dog.run(); // 继承自Mammal类
        dog.bark(); // 自己添加的方法
    }
}

在这个例子中,Dog类继承了Mammal类,而Mammal类又继承自Animal类。因此,Dog类隐式地继承了Animal类和Mammal类的所有属性和方法,包括eat()和run()方法。主方法创建了一个Dog对象,并调用了它从Animal类和Mammal类继承来的eat()和run()方法以及自己添加的bark()方法。

这个例子展示了Java继承的传递性,即当一个类继承自另一个类时,它将继承其父类的所有属性和方法,并且可以添加自己的属性和方法。

4.1.3重写父类方法

在Java中,子类可以重写父类的方法,并且可以覆盖父类中的方法实现,以满足自己的需求。在子类中重写父类的方法时,必须保证方法名、参数列表和返回值类型都相同。

下面是一个简单的Java重写父类方法的例子:

class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    @Override // 用@Override注解指示该方法是重写父类方法
    public void eat() {
        System.out.println("Dog is eating");
    }

    public void bark() {
        System.out.println("Dog is barking");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); // 调用重写后的方法
        dog.bark(); // 自己添加的方法
    }
}

在这个例子中,Dog类重写了Animal类中的eat()方法,并改变了它的行为。主方法创建了一个Dog对象并调用了它从Animal类继承来的eat()方法(实际上调用的是重写后的方法)和自己添加的bark()方法。

需要注意的是,如果父类中某个方法被声明为final,则该方法不能被子类重写;如果父类中某个方法被声明为private,则该方法不能被子类访问或重写;如果子类中重写父类的方法时,子类的访问修饰符不能低于父类的访问修饰符。

4.2方法重写

在Java中,方法重写是指子类实现一个与父类同名、同参数列表和同返回值类型的方法,从而覆盖父类中的方法。方法重写可以用于改变父类方法的行为,使得子类能够根据自己的需求来实现相应的方法。

方法重写需要满足以下几个条件:

1.子类的方法必须与父类的方法具有相同的名称、参数列表和返回类型。
2.子类的访问修饰符不能低于父类的访问修饰符。即如果父类的方法被声明为public,则子类的方法也必须被声明为public;如果父类的方法被声明为protected,则子类的方法可以被声明为protected或public;如果父类的方法没有访问修饰符,则子类的方法也必须没有访问修饰符或者被声明为protected。
3.子类的方法不能抛出比父类方法更宽泛的异常。也就是说,子类的方法所抛出的异常必须是父类方法所抛出异常的子类或者兄弟类。

Java中方法重写的特点如下:

1.子类中的方法必须与父类中的方法具有相同的名称、参数列表和返回类型,否则会产生编译错误。
2.子类中的方法不能低于父类中的方法的访问权限,即如果父类方法被声明为public,则子类方法也必须被声明为public;如果父类方法被声明为protected,则子类方法可以被声明为protected或public;如果父类方法没有访问修饰符,则子类方法也必须没有访问修饰符或者被声明为protected。
子类中的方法可以抛出比父类方法更少的异常,但不能抛出比父类方法更宽泛的异常,否则会产生编译错误。
3.方法重写只发生在父类和子类之间,不同的子类可以分别重写父类中的同名方法。
4.方法重写可以用于改变父类方法的行为,使得子类能够根据自己的需求来实现相应的方法。
5.需要注意的是,Java中方法重写是一种运行时多态的体现,即在程序运行时,根据实际对象的类型来调用相应的方法。因此,在进行方法重写时,应该遵循“Liskov替换原则”,即子类对象可以替换父类对象,而程序的行为不会受到影响。此外,使用@Override注解可以让编译器检查该方法是否真正地覆盖父类中的方法。

在Java中,方法重写是一种常见的面向对象编程技术,但是在进行方法重写时需要注意以下几点:

1.方法名、参数列表和返回类型必须与父类方法完全相同,否则会产生编译错误。
2.子类方法的访问权限不能低于父类方法的访问权限,即如果父类方法被声明为public,则子类方法也必须被声明为public;如果父类方法被声明为protected,则子类方法可以被声明为protected或public;如果父类方法没有访问修饰符,则子类方法也必须没有访问修饰符或者被声明为protected。
3.子类方法不能抛出比父类方法更宽泛的异常,否则会产生编译错误。如果子类方法需要抛出新的异常,可以使用try-catch语句捕获并处理异常。
4.如果父类方法被声明为final,则不能被子类重写。
5.如果父类方法被声明为static,则不能被子类重写,因为静态方法是属于类的,而不是属于对象的。
6.在进行方法重写时,应该遵循“Liskov替换原则”,即子类对象可以替换父类对象,而程序的行为不会受到影响。
总之,在进行方法重写时,需要保证方法签名(方法名、参数列表和返回类型)与父类方法完全相同,并且遵循Java访问权限和异常抛出的规则,同时避免使用final或static修饰符

4.3 super关键字

在Java中,super是一个关键字,用于访问父类中的属性和方法。通过super关键字,可以在子类中访问父类中被覆盖的方法和隐藏的属性。

super关键字有两种使用方式:

1.调用父类构造方法:当子类要实例化时,需要调用其父类的构造方法来完成父类的初始化工作。子类通过使用super关键字来调用父类的构造方法,并传递相应的参数。

public class ChildClass extends ParentClass {
    public ChildClass(int arg1, int arg2) {
        super(arg1); // 调用父类构造方法
        // 子类自己的初始化工作
    }
}

2.访问父类方法或属性:当子类重写了父类中的某个方法或者需要访问父类中被隐藏的属性时,可以使用super关键字来访问父类中的方法或属性。

public class Animal {
    private String name = "Animal";
    
    public void eat() {
        System.out.println("Animal is eating");
    }
    
    public String getName() {
        return name;
    }
}

public class Dog extends Animal {
    private String name = "Dog";
    
    @Override
    public void eat() {
        super.eat(); // 调用父类中的方法
        System.out.println("Dog is eating");
    }
    
    public String getParentName() {
        return super.getName(); // 访问父类中的属性
    }
    
    public String getName() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); // 调用重写后的方法
        System.out.println(dog.getParentName()); // 访问父类中的属性
        System.out.println(dog.getName()); // 访问子类中的属性
    }
}

在上述示例代码中,Dog类继承了Animal类,并重写了Animal类中的eat()方法。在重写eat()方法时,使用了super关键字来调用父类中的eat()方法,并在其后面添加了一个新的输出语句。此外,Dog类还实现了getParentName()方法,该方法使用super关键字来访问父类中被隐藏的name属性。

总之,Java中的super关键字可以用于调用父类构造方法,访问父类中的方法或属性,在进行面向对象编程时非常有用。

4.4 final关键字

在Java中,final是一个关键字,用于修饰类、方法和变量。final关键字的作用是使得被修饰的类、方法或变量不可改变。

1.final修饰类:当一个类被final修饰时,说明该类不能被继承。也就是说,final类是一个不能有子类的类。

public final class MyClass {
    // 类的成员变量和方法
}

2.final修饰方法:当一个方法被final修饰时,说明该方法不能被子类重写。也就是说,final方法是一个不能被覆盖的方法。

public class ParentClass {
    public final void print() {
        System.out.println("ParentClass");
    }
}

public class ChildClass extends ParentClass {
    // 下面的代码会产生编译错误,因为print()方法被final修饰
    // @Override 
    // public void print() { 
    //     System.out.println("ChildClass"); 
    // } 
}

3.final修饰变量:当一个变量被final修饰时,说明该变量只能被赋值一次,即其值不能再发生变化。也就是说,final变量是一个常量。

public class MyClass {
    public static final int VALUE = 100; // 声明一个常量
    public final int size = 10; // 实例变量,在构造方法中可以被初始化

    public void method() {
        final int count = 20; // 局部变量,只能被赋值一次
        // 下面的代码会产生编译错误,因为count是一个常量
        // count = 30;
    }
}

public class MyClass {
    public static final int VALUE = 100; // 声明一个常量
    public final int size = 10; // 实例变量,在构造方法中可以被初始化

    public void method() {
        final int count = 20; // 局部变量,只能被赋值一次
        // 下面的代码会产生编译错误,因为count是一个常量
        // count = 30;
    }
}

需要注意的是,final关键字在Java中有很多应用场景。比如,在多线程编程中,可以使用final修饰变量来避免线程安全问题;在单例模式中,可以使用final修饰类来保证只有一个实例。此外,在进行性能优化时,也可以使用final关键字来提高程序的执行效率。

4.5抽象类和接口

在Java中,抽象类是一种特殊的类,用于表示不能被实例化的类。抽象类一般用于定义模板或规范,并且不能直接创建对象的情况。

抽象类的特点如下:

1.抽象类不能被实例化,只能被继承。
2.抽象类可以包含抽象方法和非抽象方法。抽象方法是没有具体实现的方法,需要子类来实现;非抽象方法有具体的实现,并且可以被子类继承或者重写。
3.子类在继承抽象类时,必须实现抽象类中所有的抽象方法,否则这个子类也必须声明为抽象类。

下面是一个简单的抽象类的例子:

public abstract class Shape {
    private String color;

    public Shape(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    // 定义了一个抽象方法,不包含具体实现
    public abstract double getArea();
}

public class Rectangle extends Shape {
    private double length;
    private double width;

    public Rectangle(String color, double length, double width) {
        super(color);
        this.length = length;
        this.width = width;
    }

    @Override
    public double getArea() {
        return length * width;
    }
}

public class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape1 = new Rectangle("red", 5, 6);
        Shape shape2 = new Circle("blue", 3);

        System.out.println(shape1.getColor() + " rectangle area is " + shape1.getArea());
        System.out.println(shape2.getColor() + " circle area is " + shape2.getArea());
    }
}

在这个例子中,Shape类是一个抽象类,包含了一个私有成员变量color和一个公共的getColor()方法。Shape类还定义了一个抽象的getArea()方法,该方法不包括具体实现,并且需要子类来实现。

Rectangle和Circle类继承自Shape类,并覆盖了getArea()方法以提供具体的实现。Main类创建了一个Rectangle对象和一个Circle对象,并调用它们的getColor()和getArea()方法。

总之,抽象类是一种不能被实例化的类,主要用于定义模板或规范,而抽象方法则是没有具体实现的方法,需要子类来实现。在使用抽象类时,需要注意子类必须实现所有的抽象方法。

4.5.2 接口

在Java中,接口是一种特殊的抽象类,其中所有的方法都没有具体实现。接口定义了一组可以被其他类实现的方法,并且这些方法都是公共的。

与抽象类不同的是,接口中所有的方法都是抽象方法,并且不能包含实例变量或静态方法。在Java中,一个类可以实现多个接口,以便可以支持多种行为。

接口的定义方式如下:

public interface MyInterface {
    void method1(); // 抽象方法
    void method2(); // 抽象方法
}

在上面的代码中,MyInterface是一个接口,它定义了两个抽象方法:method1和method2。由于接口中的方法没有具体实现,因此在实现该接口时,必须提供方法的实现。

接口的实现方式如下:

public class MyClass implements MyInterface {
    @Override
    public void method1() {
        System.out.println("Method 1");
    }

    @Override
    public void method2() {
        System.out.println("Method 2");
    }
}

在上面的代码中,MyClass类实现了MyInterface接口,并且提供了method1和method2方法的具体实现。通过实现接口,类可以获得接口中定义的方法,并对它们进行实现。需要注意的是,实现接口时必须实现接口中定义的所有方法。

除了基本的接口之外,Java还提供了一种特殊的接口,称为函数式接口。函数式接口只包含一个抽象方法,并且可以使用Lambda表达式来实例化它们。Java 8中提供了很多内置的函数式接口,例如Consumer、Supplier和Function等。

总之,在Java中,接口是一种特殊的抽象类,用于定义一组接口方法,并且不能包含实例变量或静态方法。一个类可以实现多个接口,以便支持多种行为。接口在Java编程中有着广泛的应用。
1.接口的特点
在Java中,接口有以下几个特点:

1.接口中的所有方法都是抽象方法,并且不能包含实例变量或静态方法。
2.接口中定义的方法默认为public,因此实现类必须将这些方法声明为public。
3.一个类可以实现多个接口,并且实现类必须实现接口中定义的所有方法。
4.接口可以被其他接口继承,并且一个接口可以继承多个接口。
5.接口中定义的常量默认为public static final类型,因此可以在实现类中直接使用。
6.接口中的方法可以有默认实现或静态方法,但是必须使用default或static关键字进行修饰。

需要注意的是,接口是一种特殊的抽象类,它只定义了一组接口方法,并没有具体的实现。因此,实现接口时必须提供方法的具体实现。此外,由于Java不支持多继承,因此接口的使用非常重要。通过实现多个接口,类可以获得不同接口中定义的方法,以实现更多的行为。

下面是一个简单的接口示例:

public interface MyInterface {
    int MAX_COUNT = 100; // 定义一个常量
    void method1(); // 抽象方法
    void method2(); // 抽象方法

    default void method3() { // 默认方法
        System.out.println("This is a default method");
    }

    static void method4() { // 静态方法
        System.out.println("This is a static method");
    }
}

public class MyClass implements MyInterface {
    @Override
    public void method1() {
        System.out.println("Method 1");
    }

    @Override
    public void method2() {
        System.out.println("Method 2");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        System.out.println(MyInterface.MAX_COUNT); // 访问接口中的常量
        obj.method1(); // 调用接口实现类中的方法
        obj.method2();
        obj.method3(); // 调用接口中的默认方法
        MyInterface.method4(); // 调用接口中的静态方法
    }
}

在这个例子中,MyInterface是一个接口,定义了两个抽象方法method1和method2,并且包含一个常量MAX_COUNT、一个默认方法method3和一个静态方法method4。接口的实现类MyClass实现了接口中的所有方法,并可以直接使用接口中定义的常量、默认方法和静态方法。

总之,接口是一种特殊的抽象类,在Java编程中占有重要地位。接口的主要作用是定义一组接口方法,并且可以被其他类或接口进行实现。接口的特点包括抽象方法、多继承、常量、默认方法和静态方法等。
接口中的属性
在Java中,接口可以定义常量,但是不能定义实例变量。在接口中定义的常量默认为public static final类型,也就是说,它们是公共的、静态的和不可修改的。

下面是一个简单的接口常量示例:

public interface MyInterface {
    int MAX_COUNT = 100; // 定义一个常量
}

public class MyClass implements MyInterface {
    public void method() {
        System.out.println("MAX_COUNT: " + MAX_COUNT); // 访问接口中的常量
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.method(); // 调用方法并访问接口中的常量
    }
}

在这个例子中,MyInterface是一个接口,定义了一个常量MAX_COUNT,它是公共的、静态的和不可修改的。MyClass实现了该接口,并且包含一个method()方法,该方法可以访问接口中的常量。Main类创建了一个MyClass对象,并调用它的method()方法来测试。

需要注意的是,接口中定义的常量是公共的、静态的和不可修改的。因此,可以直接通过接口名和常量名来访问。在实现类中,可以使用该常量来完成特定的操作。由于接口中的常量是静态的,因此可以被所有实现该接口的类所共享。

总之,在Java中,接口可以定义常量,但是不能定义实例变量。接口中定义的常量默认为public static final类型,也就是说,它们是公共的、静态的和不可修改的。在实现类中,可以通过接口名和常量名来访问这些常量。
接口中的方法
在Java中,接口中的方法都是抽象方法,也就是说,它们没有具体实现。接口用于定义一组行为,并且由实现类来提供具体的实现。

需要注意的是,接口中的所有方法默认为public abstract类型,因此在实现接口时,需要将这些方法声明为public。此外,从Java 8开始,接口还可以包含默认方法和静态方法,这些方法有具体实现,并且可以在接口中直接使用。

下面是一个简单的接口示例:

public interface MyInterface {
    void method1(); // 抽象方法
    void method2(); // 抽象方法

    default void method3() { // 默认方法
        System.out.println("This is a default method");
    }

    static void method4() { // 静态方法
        System.out.println("This is a static method");
    }
}

public class MyClass implements MyInterface {
    @Override
    public void method1() {
        System.out.println("Method 1");
    }

    @Override
    public void method2() {
        System.out.println("Method 2");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.method1(); // 调用接口实现类中的方法
        obj.method2();
        obj.method3(); // 调用接口中的默认方法
        MyInterface.method4(); // 调用接口中的静态方法
    }
}

在这个例子中,MyInterface是一个接口,定义了两个抽象方法method1和method2,并且包含一个默认方法method3和一个静态方法method4。MyClass实现了该接口,并且提供了method1和method2方法的具体实现。Main类创建了一个MyClass对象,并调用它们的方法来测试。

需要注意的是,接口中的抽象方法必须在实现类中提供具体实现,否则实现类也必须被声明为抽象类。默认方法和静态方法有具体的实现,并且可以在接口中直接使用。默认方法可以被实现类继承或者重写,而静态方法只能通过接口名来访问。

总之,在Java中,接口用于定义一组行为,并且由实现类来提供具体的实现。接口中定义的方法包括抽象方法、默认方法和静态方法等。在使用接口时,需要将抽象方法在实现类中提供具体实现,并且可以直接使用接口中的默认方法和静态方法。
接口中的多继承
在Java中,接口支持多继承。也就是说,一个接口可以继承自多个接口,并且一个类可以实现多个接口。

下面是一个简单的多继承示例:

public interface MyInterface1 {
    void method1(); // 抽象方法
}

public interface MyInterface2 {
    void method2(); // 抽象方法
}

public interface MyInterface3 extends MyInterface1, MyInterface2 {
    void method3(); // 抽象方法
}

public class MyClass implements MyInterface3 {
    @Override
    public void method1() {
        System.out.println("Method 1");
    }

    @Override
    public void method2() {
        System.out.println("Method 2");
    }

    @Override
    public void method3() {
        System.out.println("Method 3");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.method1(); // 调用接口实现类中的方法
        obj.method2();
        obj.method3();
    }
}

在这个例子中,MyInterface1和MyInterface2是两个接口,分别定义了method1和method2两个抽象方法。MyInterface3继承自这两个接口,并且定义了一个新的抽象方法method3。MyClass实现了该接口,并且提供了三个方法的具体实现。Main类创建了一个MyClass对象,并调用它们的方法来测试。

需要注意的是,当一个接口继承自多个接口时,需要保证这些接口之间没有方法名冲突。否则,在实现该接口时,必须明确指定要实现的方法。

总之,在Java中,接口支持多继承,一个接口可以继承自多个接口,并且一个类可以实现多个接口。多继承可以让我们更加灵活地组合接口,以满足不同的需求。
继承父类的同时实现接口
在Java中,一个类可以同时继承自一个父类并且实现多个接口。这样的做法可以让我们更加灵活地组合代码,并且实现多种行为。

下面是一个简单的示例:

public class MyBaseClass {
    public void myMethod() {
        System.out.println("This is a method of MyBaseClass");
    }
}

public interface MyInterface1 {
    void method1(); // 抽象方法
}

public interface MyInterface2 {
    void method2(); // 抽象方法
}

public class MyClass extends MyBaseClass implements MyInterface1, MyInterface2 {
    @Override
    public void method1() {
        System.out.println("Method 1");
    }

    @Override
    public void method2() {
        System.out.println("Method 2");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.myMethod(); // 调用继承自父类的方法
        obj.method1(); // 调用实现接口中的方法
        obj.method2();
    }
}

在这个例子中,MyBaseClass是一个父类,定义了一个myMethod()方法。MyInterface1和MyInterface2是两个接口,分别定义了method1和method2两个抽象方法。MyClass继承自MyBaseClass并且实现了这两个接口。Main类创建了一个MyClass对象,并调用它们的方法来测试。

需要注意的是,在一个类继承自父类并且实现多个接口时,需要先使用extends关键字继承父类,然后使用implements关键字实现接口。在实现接口时,需要提供所有抽象方法的具体实现。

总之,在Java中,一个类可以同时继承自一个父类并且实现多个接口。这样的做法可以让我们更加灵活地组合代码,并且实现多种行为。
接口的传递性
在Java中,接口支持传递性。也就是说,一个接口可以继承自另一个接口,并且实现类只需要实现最终的子接口即可。

下面是一个简单的示例:

public interface MyInterface1 {
    void method1(); // 抽象方法
}

public interface MyInterface2 extends MyInterface1 {
    void method2(); // 抽象方法
}

public interface MyInterface3 extends MyInterface2 {
    void method3(); // 抽象方法
}

public class MyClass implements MyInterface3 {
    @Override
    public void method1() {
        System.out.println("Method 1");
    }

    @Override
    public void method2() {
        System.out.println("Method 2");
    }

    @Override
    public void method3() {
        System.out.println("Method 3");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.method1(); // 调用接口实现类中的方法
        obj.method2();
        obj.method3();
    }
}

在这个例子中,MyInterface1是一个接口,定义了method1这个抽象方法。MyInterface2继承自MyInterface1并且定义了一个新的抽象方法method2。MyInterface3继承自MyInterface2并且定义了另一个新的抽象方法method3。MyClass实现了MyInterface3并提供了这三个方法的具体实现。Main类创建了一个MyClass对象,并调用它们的方法来测试。

需要注意的是,在一个接口继承自另一个接口时,实现类只需要实现最终的子接口即可。也就是说,如果一个类实现了MyInterface3,那么它也同时实现了MyInterface2和MyInterface1。

总之,在Java中,接口支持传递性,一个接口可以继承自另一个接口,并且实现类只需要实现最终的子接口即可。

你可能感兴趣的:(java,开发语言,jvm)