Java语法相关知识汇总(三)

第一章、Java帮助文本与核心类库

javaSE API 帮助文档

java类库一般都包括三个部分

  • 源码:可以看源码来理解程序
  • 字节码:程序开发的过程使用的就是字节码文件
  • 帮助文档:对开发提供帮助

注意版本统一

第二章、OCP原则

应该通过添加新的代码来扩展现有代码,而不是修改现有代码

首选多态语法

        程序编程中的OCP原则是指“开放/关闭原则”(Open/Closed Principle),是SOLID原则中的一个。OCP原则的定义是:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着在不修改现有代码的情况下,可以通过添加新的功能来扩展现有代码。

        具体而言,OCP原则要求在设计和实现软件时,应该将不同的职责分离成不同的模块或组件。这样,当需要添加新的功能时,可以通过创建新的模块或组件来扩展现有代码,而不必修改现有代码。这种做法有助于提高代码的可维护性、可扩展性和可重用性。

一、开放性(Open for Extension)

        软件实体应该允许在不修改其现有代码的情况下进行扩展。这意味着可以通过添加新的代码来增加功能,而不会影响已经存在的代码。

二、封闭性(Closed for Modification)

        一旦软件实体的行为被确定,就应该尽量避免修改其现有的代码。这是为了防止已经存在的代码被意外破坏,从而提高代码的稳定性和可靠性。

        例如,在面向对象编程中,可以通过使用接口和抽象类来实现OCP原则。一个类实现了一个接口或继承了一个抽象类,可以保证在不修改原有代码的情况下,对其进行扩展和改进。

        总之,OCP原则是一种重要的软件设计原则,它有助于提高代码的质量和可维护性。

第三章、抽象类与抽象方法

一、抽象类概述

  • 类到对象是实例化。对象到类是抽象。
  • 抽象类 --实例化--》类,类 --抽象--》 抽象类

1、概念

  • 类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类。
  • 类本身是不存在的,所以抽象类无法创建对象《无法实例化》。
  • 抽象类也属于引用数据类型
  • java 中所有的类,包括抽象类,都继承自 Object 类
  • 抽象类是无法实例化的,无法创建对象的,所以抽象类是用来被子类继承的,抽象类只能作为父类。
  • final和abstract不能联合使用,这两个关键字是对立的
    • final关键字用来修饰一个变量、方法或类。对于一个final修饰的类,是不能被继承的,而抽象类不能实例对象,要被子类继承,所以会语法冲突

  • 抽象类的子类可以是抽象类也可以是非抽象类。
  • 抽象类虽然无法实例化,但是抽象类有构造方法,子类构造方法中默认的 super()来调用父类中的构造方法

抽象类概念图示:

2、定义语法

【访问权限控制符列表】 abstract  class  类名{

        类体;

  }

package 抽象类与抽象方法;

public abstract class AbstractTest01 {
}

3、抽象类中可以有的内容

1、实例变量(没有abstract修饰符)

2、实例方法(没有abstract修饰符)

3、构造方法(没有abstract修饰符)

4、静态变量(没有abstract修饰符)

5、静态方法(没有abstract修饰符)

6、抽象方法:没有方法体的实例方法(有abstract修饰符)

package 抽象类与抽象方法;

public abstract class AbstractTest01 {
    //实例变量
    public String instanceVariable;

    //实例方法
    public void instanceMethod() {
        System.out.println("实例方法");
    }

    //构造方法
    public AbstractTest01(String instanceVariable) {
        this.instanceVariable = instanceVariable;
        System.out.println("构造方法");
    }

    //静态变量
    public static String staticVariable = "静态变量";
    //静态方法
    public static void staticMethod(){
        System.out.println("静态方法");
    }

    //抽象方法
    public abstract void abstractMethod();



    public static void main(String[] args) {
        //匿名内部类写法
        AbstractTest01 abstractTest01 = new AbstractTest01("实例变量") {
            @Override
            public void abstractMethod() {
                System.out.println("抽象方法(没有方法体的实例方法)");
            }
        };

        System.out.println(abstractTest01.instanceVariable);
        abstractTest01.instanceMethod();
        System.out.println(AbstractTest01.staticVariable);
        AbstractTest01.staticMethod();

        abstractTest01.abstractMethod();
        /**
         * 构造方法
         * 实例变量
         * 实例方法
         * 静态变量
         * 静态方法
         * 抽象方法(没有方法体的实例方法)
         */
    }
}

//非抽象子类继承抽象类写法
class ImplementClass extends AbstractTest01{
    public ImplementClass(String instanceVariable) {
        super(instanceVariable);
    }
    @Override
    public void abstractMethod() {

    }
}

         如果在抽象类中定义静态变量,那么这个静态变量也是属于类级别的,和普通的类一样。子类继承这个抽象类后,也会继承它的静态变量,可以直接使用类名访问。

下面是一个简单的 Java 抽象类示例,其中定义了一个静态变量:

abstract class Shape {
    protected String color;
    public static int count = 0;
    
    public Shape(String color) {
        this.color = color;
        count++;
    }
    
    public void setColor(String color) {
        this.color = color;
    }
    
    public abstract double getArea();
}

在这个例子中,抽象类 Shape 定义了一个静态变量 count,并在构造函数中对其进行了自增操作。子类可以直接访问这个静态变量,例如:

class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    public static void main(String[] args) {
        Circle circle = new Circle("red", 5.0);
        System.out.println(Shape.count);  // 输出 1
    }
}

        在这个例子中,子类 Circle 直接访问了抽象类 Shape 中定义的静态变量 count。因为 Circle 类是 Shape 类的子类,所以它可以访问 Shape 类中的所有静态变量和方法。

二、抽象方法概述

1、概念

1、抽象方法表示没有实现的方法,没有方法体的方法。要想继承到非抽象子类中则必须将其实现。

2、可理解为没有方法体的实例方法,例如:public abstract void dosome() :

java语言中凡是没有方法体的方式都是抽象方法吗? 错误

Object类中就有很多方法都没有方法体,都是以“;”结尾的,但他们都不是抽象方法,例如:

public native int hashCode();

//该方法底层调用了C++的动态链接库程序,native表示调用JVM本地程序

2、定义语法

1、没有方法体,以分号结尾

2、前面修饰符列表中有abstract关键字

3、static和abstract不能联合使用   

  • static关键字用来修饰静态方法,表示这个方法是属于类而不是对象的。这意味着,可以在不创建类的实例的情况下直接调用静态方法。而且,静态方法可以直接通过类名访问。
  • abstract关键字用来修饰抽象方法,表示这个方法没有实现,需要在子类中被重写。抽象方法必须被声明在抽象类或接口中,这些类或接口本身是不能被实例化的。
  • 因为static方法是属于类的,而abstract方法必须在子类中被重写,所以这两个关键字的语义是相互矛盾的。如果在同一个方法中同时使用这两个关键字,就会导致语法错误

4、final和abstract不能联合使用

  • final关键字用来修饰一个变量、方法或类。对于一个final方法,它的实现不能被子类重写,因此这个方法的行为是不可变的。而abstract关键字则用来修饰一个抽象方法,表示这个方法只是一个接口,需要在子类中被实现。
  • 因为final方法的实现是不可变的,而abstract方法需要在子类中被实现,所以这两个关键字的语义是相互矛盾的。如果在同一个方法中同时使用这两个关键字,就会导致语法错误。

5、private和abstract不能联合使用

  • private修饰的属性和方法不能被子类所继承,而abstract修饰的抽象方法必须要被非抽象子类重写,重写的前提就是要继承,所以private和abstract不能联合使用

三、抽象类与抽象方法的关系

1、抽象类中可以有或没有抽象方法或非抽象方法

2、抽象类中不一定有抽象方法,但是抽象方法必须出现在抽象类或接口中

3、一个非抽象的类继承抽象类,必须将抽象类中的抽象方法进行重写/覆盖,或者称为“对抽象的实现”

四、抽象类的子类也可以是抽象类

        在 Java 中,抽象类的子类也可以是抽象类。这种继承关系可以一直延续下去,子类可以选择性地实现抽象方法,或者继续声明新的抽象方法。

具体来说,在 Java 中:

  1. 抽象类可以继续被继承,子类可以选择性地实现抽象方法,或者继续声明新的抽象方法。
  2. 抽象类的子类如果没有实现父类的所有抽象方法,那么子类本身也必须声明为抽象类。

以下是一个 Java 示例,说明了抽象类的子类也可以是抽象类:

abstract class AbstractShape {
    abstract double area();
}

abstract class AbstractPolygon extends AbstractShape {
    abstract int sides();
}

class Triangle extends AbstractPolygon {
    private double base;
    private double height;

    Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }

    double area() {
        return 0.5 * base * height;
    }

    int sides() {
        return 3;
    }
}

abstract class Quadrilateral extends AbstractPolygon {
    abstract double diagonal();
}

class Rectangle extends Quadrilateral {
    private double width;
    private double height;

    Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    double area() {
        return width * height;
    }

    int sides() {
        return 4;
    }

    double diagonal() {
        return Math.sqrt(width * width + height * height);
    }
}

public class Main {
    public static void main(String[] args) {
        Triangle triangle = new Triangle(4, 5);
        Rectangle rectangle = new Rectangle(3, 6);

        System.out.println("Triangle Area: " + triangle.area());       // 输出: Triangle Area: 10.0
        System.out.println("Triangle Sides: " + triangle.sides());     // 输出: Triangle Sides: 3
        System.out.println("Rectangle Area: " + rectangle.area());     // 输出: Rectangle Area: 18.0
        System.out.println("Rectangle Sides: " + rectangle.sides());   // 输出: Rectangle Sides: 4
        System.out.println("Rectangle Diagonal: " + rectangle.diagonal()); // 输出: Rectangle Diagonal: 6.708203932499369
    }
}

        在这个 Java 示例中,AbstractPolygonAbstractShape 的子类,QuadrilateralAbstractPolygon 的子类,TriangleRectangle 分别是 AbstractPolygonQuadrilateral 的子类。这种继承关系形成了一个层次结构,子类可以选择性地实现父类的抽象方法,或者继续声明新的抽象方法。 

package com.javase.抽象类;

public class AbstractTest01 {
    public static void main(String[] args) {
        //java: com.javase.抽象类.Account是抽象的; 无法实例化
        //new Account();
    }
}

//抽象类
//java: 非法的修饰符组合: abstract和final
/*final abstract class Account extends Object{

}*/

//抽象类
abstract class Account extends Object{
    public Account(){
        super();
    }

    //抽象方法
    public abstract void doSome();

    //非抽象方法
    public void doOther(){

    }
}

//子类继承抽象类,子类可以实例对象
/*class CreditAccount extends Account{
    public CreditAccount(){
        super();
    }
}*/

//抽象类的子类也可以是抽象类
/*
abstract class CreditAccount extends Account{

}*/

五、一个非抽象的类继承抽象类,必须将抽象类中的所有抽象方法进行重写/覆盖

        在 Java 中,一个非抽象的类继承抽象类时,必须实现抽象类中的所有抽象方法。这是因为抽象方法在抽象类中只有方法签名,没有具体的实现,而子类必须提供这些方法的具体实现。

如果一个非抽象的类继承了一个抽象类但没有实现抽象方法,那么这个子类本身也会被视为抽象类,无法被实例化。

以下是一个 Java 示例,演示了一个非抽象的类继承抽象类并实现抽象方法的情况:

abstract class AbstractShape {
    abstract double area();
}

class Circle extends AbstractShape {
    private double radius;

    Circle(double radius) {
        this.radius = radius;
    }

    double area() {
        return 3.14159 * radius * radius;
    }
}

class Square extends AbstractShape {
    private double side;

    Square(double side) {
        this.side = side;
    }

    double area() {
        return side * side;
    }
}

public class Main {
    public static void main(String[] args) {
        Circle circle = new Circle(5);
        Square square = new Square(4);

        System.out.println("Circle Area: " + circle.area());     // 输出: Circle Area: 78.53975
        System.out.println("Square Area: " + square.area());     // 输出: Square Area: 16.0
    }
}

        在这个 Java 示例中,CircleSquare 都是非抽象的子类,它们继承了 AbstractShape 并实现了 area 抽象方法,提供了具体的计算面积的实现。

        如果 CircleSquare 没有提供 area 方法的实现,它们将被视为抽象类,无法实例化。这是确保抽象类的抽象方法得到了正确实现的一种机制。

package com.javase.抽象类;

public class AbstractTest02 {
    public static void main(String[] args) {
        //面向抽象编程,不要面向具体编程,降低程序的耦合度,提高程序的扩展力,符合OCP原则
        Animal a = new Bird(); //向上转型

        /*
        * 编译时:
        *   静态绑定为Animal中的move方法
        * 运行时:
        *   动态绑定为Bird中的move方法
        * */
        a.move();
        Bird b = (Bird) a;
        b.m1();
    }
}

//抽象类
abstract class Animal extends Object{

    //定义抽象方法
    public abstract void move();

}

//非抽象子类
//java: com.javase.抽象类.Bird不是抽象的, 并且未覆盖com.javase.抽象类.Animal中的抽象方法move()
/*
class Bird extends Animal{

}*/

//非抽象子类
class Bird extends Animal{
    //需要将父类中继承过来的抽象方法进行覆盖/重写,或者也可以叫做“实现”
    public void move(){
        System.out.println("鸟儿在飞翔!");
    }

    public void m1(){
        System.out.println("m1");
    }
}

//抽象子类:如果子类也是抽象的,则不需要覆盖,重写,或者实现父类中的抽象方法
/*
abstract class Bird extends Animal{
//    public abstract void move();
}*/

第四章、接口(interface  完全抽象类)

一、接口概述

1、接口是完全抽象类

接口是完全抽象的。(抽象类是半抽象)   或者也可以说接口是特殊的抽象类

        接口是一种定义了一组方法签名的抽象类型。它只描述了方法应该做什么,而不涉及具体的实现。接口定义了一种协议或契约,它规定了类必须实现的方法和行为。可以理解为:接口是特殊完全抽象的类,不是继承于Object

2、接口是用于数据类型

接口也是一种“引用数据类型”。编译之后也是一个class字节码文件

3、接口的意义

        接口的主要目的是定义一组规范或契约,而不是提供具体的实现。通过实现接口,类可以遵循接口定义的规范并提供相应的方法实现。这种设计提供了一种分离接口和实现的方式,增加了代码的灵活性和可维护性。

接口就像是可插拔的内存条,通常提取的是行为动作

4、接口并不继承Object类

        在Java中,接口(interface)并不直接继承自Object类。接口是一种抽象类型,它定义了一组方法的签名,但没有实现这些方法的具体细节。由于接口不包含成员变量或方法的实现,因此它不需要继承自Object类。

        尽管接口本身不继承自Object类,但实现接口的类是继承自Object类的。当一个类实现了一个接口时,它默认继承了Object类,并且可以使用Object类中的方法。

        无论类是否实现了接口,所有的类在Java中都会隐式地继承自Object类。这意味着即使一个类没有显式地声明它继承自Object类,它仍然会继承Object类的方法和行为。

        需要注意的是,接口中的方法都是隐式地被声明为抽象方法,而抽象方法本身是没有方法体的。因此,接口中的方法不同于Object类中的方法,后者有默认的实现。

二、语法

 [修饰符列表]  interface  接口名{

        常量;//默认为静态属性  public  static  final

        抽象方法;//默认为实例方法  public  abstract 

}

三、接口支持多继承

接口支持多继承,一个接口可以继承(extends)多个接口

        在Java中,接口是一种特殊类型的类,它只包含抽象方法的定义。与类不同,Java接口支持多继承,这意味着一个接口可以继承多个其他接口。这种多继承的概念称为"接口多继承"或"接口继承"。

        当一个接口继承多个接口时,它会继承这些接口的所有抽象方法,并将它们合并到自己的接口定义中。这样,实现这个接口的类就需要提供实现所有继承的接口中的抽象方法。

下面是一个示例来说明接口的多继承:

// 定义接口A
interface A {
    void methodA();
}

// 定义接口B
interface B {
    void methodB();
}

// 定义接口C,继承接口A和接口B
interface C extends A, B {
    void methodC();
}

// 实现接口C的类
class MyClass implements C {
    public void methodA() {
        System.out.println("实现接口A的方法");
    }

    public void methodB() {
        System.out.println("实现接口B的方法");
    }

    public void methodC() {
        System.out.println("实现接口C的方法");
    }
}

// 主类
public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.methodA();
        obj.methodB();
        obj.methodC();
    }
}

        在上面的示例中,接口A定义了方法methodA,接口B定义了方法methodB,接口C继承了接口A和接口B,并定义了方法methodC。然后,类MyClass实现了接口C,并提供了对所有三个方法的实现。

        在主类Main中,我们创建了MyClass的实例并调用了三个方法。由于MyClass实现了接口C,它必须提供对所有三个方法的实现。因此,输出将会是:

实现接口A的方法
实现接口B的方法
实现接口C的方法

        这个例子展示了接口多继承的概念。通过继承多个接口,可以将多个接口的功能组合到一个接口中,并通过实现这个接口的类来提供实现。这样的设计可以帮助实现代码的灵活性和重用性。

四、接口中内容

1、接口中只包含两部分内容,一部分是:常量。一部分是:抽象方法。接口中没有其它内容(老版本的JDK中是这样的)

2、接口中所有的元素都是public修饰的。(都是公开的)

3、接口中的抽象方法定义时public abstract修饰符可以省略。

4、接口中的常量定义时: public static final可以省略。

5、接口中的方法都是抽象方法,所以接口中的方法不能有方法体

1、抽象方法(Abstract Methods)实例方法

        接口中的方法没有具体的实现,只有方法的声明,没有方法体。它们通常没有方法体是因为接口用于定义一组规范,而具体的实现由实现接口的类提供。

1.1、接口中的抽象方法只能是public abstract 修饰的

接口中的抽象方法只能是public abstract修饰,可以省略

抽象类中的抽象方法除了不能使用private修饰外,缺省,protected,public 都可以搭配abstract修饰

2、常量(Constants)(实例变量/静态变量)

        接口中可以包含常量,这些常量默认为public static final,也就是说它们是公共的、静态的和不可修改的。在接口中定义的常量可以在实现类中直接访问。

3、嵌套接口(默认为public static)

在Java中,接口内部是可以嵌套其他接口的,也就是一个接口可以包含另一个接口

// 定义接口A
interface A {
    void methodA();

    // 嵌套接口B
    //默认为public static
    public static interface B {
        void methodB();
    }
}

// 实现接口A和接口A中的嵌套接口B
class MyClass implements A,A.B {
    @Override
    public void methodA() {
        System.out.println("实现接口A的方法");
    }

    @Override
    public void methodB() {
        System.out.println("实现接口B的方法");
    }
}

// 使用接口和实现类
public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        
        //A类型不行,没有methodB方法,静态绑定失败,编译报错
//        A obj = new MyClass();

        //A.B类型不行,没有methodA方法,静态绑定失败,编译报错
//        A.B obj = new MyClass();

        obj.methodA(); // 调用接口A中的方法
        obj.methodB(); // 调用接口B中的方法
    }
}

        在上面的示例中,接口A内部嵌套了接口B,并分别定义了各自的方法methodAmethodB。然后,MyClass类实现了接口A和接口A中的嵌套接口B,并实现了这两个接口的方法。

        请注意,对于嵌套接口B,您可以通过"接口A.接口B"的方式来引用它。在MyClass中,我们实现了接口A和接口A中的嵌套接口B的方法,并在Main类中进行了调用。

        嵌套接口的使用可以帮助组织和结构化代码,尤其在一个接口中定义了多个相关联的子接口时,可以增强代码的可读性和可维护性。

4、新特性:默认方法(Default Methods)

        在 Java 8 及之后的版本中,引入了接口的默认方法(Default Methods)的概念,允许接口中包含具有默认实现的方法。这使得在向现有接口添加新方法时,不会影响已经实现该接口的类,从而更好地支持接口的演化和扩展。也使得在接口的所有实现类中都有一个默认的方法实现,而不需要在每个实现类中都重复编写相同的代码。接口的默认方法在某种程度上类似于抽象类中的普通方法。

以下是关于 Java 接口默认方法的详细说明:

定义默认方法 在接口中可以定义默认方法,使用 default 关键字标记。默认方法可以提供方法的默认实现,但它们可以在实现接口的类中被覆盖。

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

    // 抽象方法(普通接口方法)
    void myAbstractMethod();
}

使用默认方法 类实现接口时,默认方法会自动继承到实现类中。实现类可以选择性地覆盖默认方法,提供自己的实现。

class MyClass implements MyInterface {
    @Override
    public void myAbstractMethod() {
        System.out.println("Implementing myAbstractMethod.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.myDefaultMethod();       // 输出: This is a default method.
        obj.myAbstractMethod();      // 输出: Implementing myAbstractMethod.
    }
}

5、新特性:静态方法(Static Methods)

静态方法不会被子接口继承,也不会被实现接口的类继承。它们只能通过接口名调用

        在 Java 8 及之后的版本中,接口(interface)可以包含静态方法。静态方法是属于接口本身的方法,可以通过接口名调用,不需要创建接口的实例。静态方法可以用于提供通用的功能或工具函数,与接口的实例无关。

静态方法与抽象方法之间有一些重要的区别:

  • 实例方法需要通过实例调用,而静态方法通过接口名调用。
  • 静态方法不能访问实例成员,只能访问静态成员。
  • 实例方法可以被子类覆盖,而静态方法不能。
interface MyInterface {
    // 静态方法
    static void myStaticMethod() {
        System.out.println("This is a static method in MyInterface.");
    }

    // 抽象方法
    void myAbstractMethod();
}

interface SubMyInterface extends MyInterface{
    
}

class MyClass implements SubMyInterface {
    @Override
    public void myAbstractMethod() {
        System.out.println("Implementing myAbstractMethod.");
    }
}

public class Main {
    public static void main(String[] args) {
        MyInterface.myStaticMethod(); // 输出: This is a static method in MyInterface.
        
        //编译报错:只能使用静态方法所在接口名调用,子接口也不行
        //SubMyInterface.myStaticMethod();
        
        //编译报错:只能使用静态方法所在接口名调用
        //Main.myStaticMethod();

        MyClass obj = new MyClass();
        obj.myAbstractMethod();       // 输出: Implementing myAbstractMethod.

        //编译报错:只能使用静态方法所在接口名调用
        //obj.myStaticMethod();

        System.out.println(obj instanceof SubMyInterface); //true
        System.out.println(obj instanceof MyInterface); //true
    }
}

        总而言之,接口是一种规范化的定义,包含了抽象方法、默认方法、静态方法和常量,用于定义类应该具备的行为和功能。

package com.javase.接口基础语法;

public class Test01 {
    public static void main(String[] args) {
        //访问接口中的常量
        System.out.println(MyMath.PI);

        //常量不能修改
        //MyMath.PI = 46;
    }
}

//定义接口:A
interface A{

}

//定义接口:B,支持继承
interface B extends A{

}

//接口支持多继承
interface C extends A,B{

}

interface MyMath{
    //常量
    public static final double PI = 3.1415926;

    //可以省略:public static final
    //接口中随便写一个变量,看着像变量,其实是省略了public static final  是常量
    int I = 8;

    //抽象方法
    public abstract int sum(int a, int b);

    //可以省略public 和 abstract
    int sum1(int a, int b);

    //编译报错:java: 接口抽象方法不能带有主体
    /*void doSome(){

    }*/

    int sub(int a, int b);
}

五、接口和类之间的关系(implements 实现)

继承关键字:extends

实现关键字:implements

  • 类和类之间叫做继承,只支持单继承
  • 接口和接口之间叫做继承,支持多继承
  • 类和接口之间叫做实现,非抽象的类可同时实现多个接口

理解为:可以将"实现"看做"继承”,但是实现并不完全是继承,只有部分继承(常量部分),实现implements有部分继承链,继承extends有全部继承链,实现的是接口,接口就像一个模具,(比如要用橡皮泥捏一个人,有很多模具,手的模具,头的模具等等,每一个模具就是一个接口,实例方法就像是手模具中每个关节的轮廓,橡皮泥自身也要按照轮廓来改变,就像是实现接口中抽象方法,默认方法就像是模具安置在橡皮泥上的,不会拿走,接口中的常量,就像是模具的logo,也会印在橡皮泥上,不会拿走,就像继承一样,接口中的静态方法就像按照模具捏的这个过程一样,捏完之后会将模具拿走,因此静态方法为接口特有的,只能用接口来调用,不会继承)将一些特定的实例方法(包括抽象方法和默认方法)强制打磨给指定的类,这样该类也会有这些特定的实例方法,具有可插拔性。

A类 实现 B接口:理解为A继承B,B的型覆盖至A

C类 继承 B类,B类 实现 A接口:理解为B继承A,A的型只能覆盖到B,不能覆盖到C

1、接口中的静态属性(常量)是隐式地被实现类继承的

        接口中的静态属性(常量)被实现类隐式继承的设计是为了提供一种便捷的方式,让实现类可以访问接口中定义的常量,以及在不引入冗余代码的情况下共享常量值。这种设计考虑了接口作为契约和规范的角色,以及实现类应该能够访问接口的常量,而不需要额外的继承或实现。

以下是一些解释为什么接口中的静态属性被隐式继承的原因:

  1. 契约的一致性: 接口代表了一种契约,即实现类应该具有一定的行为和属性。在这个契约中,常量也是一种属性。为了确保实现类遵循接口的契约,接口中的常量应该对实现类是可见的。

  2. 代码重用和简洁性: 如果实现类需要访问接口中的常量,而不隐式继承,那么每个实现类都需要显式地重复定义这些常量。这会导致冗余代码,并降低了代码的可维护性。通过隐式继承,可以在不引入冗余代码的情况下实现常量的共享和复用。

  3. 接口的目的: 接口的一个主要目的是为实现类提供一组公共行为和属性,而这些属性(包括常量)对于实现类来说应该是一致的。通过允许实现类隐式继承接口中的常量,可以更好地达到这个目的。

  4. 不破坏向后兼容性: 将接口中的常量隐式继承到实现类中,不会引入向后不兼容的改变。这意味着,如果将新的常量添加到接口中,现有的实现类仍然可以继续正常工作,因为它们已经继承了接口中的所有常量。

        总之,接口中的静态属性被隐式地继承到实现类中是为了支持契约的一致性、代码重用和简洁性,并且遵循了接口作为规范的设计目标。这种设计能够更好地满足实现类对接口常量的访问需求,同时保持代码的可维护性和向后兼容性。

package 接口;

public interface MyInterface {
    public static final double PI = 3.1415926;
}

class Math implements MyInterface{
    public static void main(String[] args) {
        System.out.println(MyInterface.PI); //3.1415926
        System.out.println(Math.PI); //3.1415926

        Math math = new Math();
        System.out.println(math.PI); //3.1415926
    }
}

2、接口中的静态方法不是隐式地被实现类继承的

        在 Java 中,接口中的静态方法不被实现类隐式继承的原因是为了避免多继承的复杂性和歧义。允许接口中的静态方法隐式继承到实现类可能会引发以下问题:

  1. 多继承冲突: 如果一个类实现了多个接口,而这些接口中都有相同的静态方法,那么在调用时就会产生冲突。这会让代码的语义变得模糊,不清楚应该调用哪个接口的静态方法。

  2. 灵活性和可理解性: 隐式继承会增加代码的复杂性,可能导致代码不够清晰和易于理解。在 Java 中,接口是一种定义契约和行为的方式,而静态方法通常提供一些通用的功能。这种分离可以让代码更加灵活和可理解。

  3. 不同接口的用途: 不同的接口可能具有不同的用途和功能,其中的静态方法也可能是不同的。在调用接口的静态方法时,需要明确指定调用的是哪个接口,以便程序员更好地理解代码的含义。

        虽然接口中的静态方法不被实现类隐式继承,但实现类仍然可以直接调用接口中的静态方法,就像调用普通的静态方法一样。这种设计可以避免冲突和混淆,同时保持代码的清晰性和可维护性。

以下是一个示例,说明为什么接口中的静态方法不隐式地被实现类继承:

interface MyInterface {
    static void myStaticMethod() {
        System.out.println("This is a static method in MyInterface.");
    }
}

class MyClass implements MyInterface {
    // 实现类不会隐式继承接口中的静态方法
}

public class Main {
    public static void main(String[] args) {
        // 不能通过实现类名调用接口的静态方法
        // MyClass.myStaticMethod(); // 编译错误

        // 可以直接通过接口名调用接口的静态方法
        MyInterface.myStaticMethod(); // 输出: This is a static method in MyInterface.
    }
}

    &nb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值