关于Java中的接口

关于Java中的接口,java,oop,interface,Java,Oop,Interface,我一直在做一些工作,遇到了一些关于接口的有趣的事情。我认为这是相当普遍的,但我对这一点还不熟悉。我只是想确定我所做的是否正确 让我们假设我有一个接口,比如说B interface B {}. 我有一个实现B的类a class A implements B { }. 现在让我们假设我们有一个C类,其中我们使用接口B class C { private B b; public void setB(B b) { this.b = b; } pub

我一直在做一些工作,遇到了一些关于接口的有趣的事情。我认为这是相当普遍的,但我对这一点还不熟悉。我只是想确定我所做的是否正确

让我们假设我有一个接口,比如说B

interface B {}.
我有一个实现B的类a

class A implements B { }.
现在让我们假设我们有一个C类,其中我们使用接口B

class C {
    private B b;

    public void setB(B b) {
        this.b = b;
    }

    public B getB() {
        return b;
    }
}
我们还有另一个测试类,如下所示:

public class TestAll {
    private final C c = new C();
    private final A a = new A();
    private final B b = null;
    void test123(){
        c.setB(a);//[1]
        c.setB(b);//[2]     
    }
}
那么现在我的问题是方法调用[1]正确还是错误?如果它是正确的,我确信它是OOP概念之一,那是什么?如果是直截了当的话,我很抱歉,我对所有这些java东西都是新手


谢谢。

[1]是正确的。根据逆变原理,您始终可以将对象作为参数传递给指定对象类或该类的任何父类作为参数的方法。

[1]是正确的。在逆变原理下,您始终可以将对象作为参数传递给指定对象类或该类的任何父类作为参数的方法。

接口表示一种抽象方式,用于划分类可以做什么以及类将如何做,因为a实现了B,这意味着A类“可以”完成接口B合同提供的功能,因此
c.setB(A)//[1] 
是100%有效的

这种方法“挫折(B)”可以理解为给我一些东西,可以做什么B提供,无论如何

Ergo:它是一个有效的方法调用


第二个调用非常明显,它是有效的。

接口代表了一种抽象的方式来划分类可以做什么以及类将如何做,因为a实现了B,这意味着类a“可以”做B合同提供的接口,因此
c.setB(a)//[1] 
是100%有效的

这种方法“挫折(B)”可以理解为给我一些东西,可以做什么B提供,无论如何

Ergo:它是一个有效的方法调用


第二个调用很明显是有效的。

我认为OOP的概念就是多态性。请看


B对象可以有多种形式和形状,例如A,但它可以是实现接口B的任何其他对象。

我认为OOP概念只是多态性。请看

class C {
    private B b;

    public void setB(B b) {
        this.b = b;
    }

    public B getB() {
        return b;
    }
}

B对象可以有多种形式和形状,例如A,但它可以是实现接口B的任何其他对象。

正确的是,您始终可以在希望继承类型(B)的任何位置传递子类型(类A实现B)

class C {
    private B b;

    public void setB(B b) {
        this.b = b;
    }

    public B getB() {
        return b;
    }
}
但是,在类B setB()中,可以将传递的参数视为B(并且不能访问类A的其他属性或方法)

我建议您首先使用纯继承实现更简单的实际项目,而不使用接口和抽象类来掌握这一切

例如,假设您正在为一家酒吧建模。在酒吧里,有人可以喝的饮料

class Drink {
   String name;
   double servingSize;

   public Drink(String name,double servingSize) {
       this.name=name;
       this.servingSize=servingSize;
   }
}

class Snaps extends Drink {
   public Snaps() {
       super("Finlandia Vodka",0,5);
   }
}

class Human {
    public void consume(Drink drink) {
        // do something
    }
}
现在你的问题是,人类是否只能消费一个饮料实例,或者也可以消费一个后代,所以,一个人类?答案当然是人类可以吃快照,因为快照是饮料的后代。人一旦能喝一种饮料,就可以喝任何饮料


我希望这能让事情更容易理解。:)

这是正确的,您总是可以传递子类型(类a实现了B),无论您期望继承类型(B)在哪里

但是,在类B setB()中,可以将传递的参数视为B(并且不能访问类A的其他属性或方法)

我建议您首先使用纯继承实现更简单的实际项目,而不使用接口和抽象类来掌握这一切

例如,假设您正在为一家酒吧建模。在酒吧里,有人可以喝的饮料

class Drink {
   String name;
   double servingSize;

   public Drink(String name,double servingSize) {
       this.name=name;
       this.servingSize=servingSize;
   }
}

class Snaps extends Drink {
   public Snaps() {
       super("Finlandia Vodka",0,5);
   }
}

class Human {
    public void consume(Drink drink) {
        // do something
    }
}
现在你的问题是,人类是否只能消费一个饮料实例,或者也可以消费一个后代,所以,一个人类?答案当然是人类可以吃快照,因为快照是饮料的后代。人一旦能喝一种饮料,就可以喝任何饮料


我希望这能让事情更容易理解。:)

编译器可以告诉你这是否正确。你说的“正确”是什么意思?它有效,而且应该有效。你试过这个吗?有错误吗?对不起,我的意思是它是正确的。编译器中没有错误。但是,我想知道这样做是否正确。我的错。错误的框架。编译器可以告诉你这是否正确。你说的“正确”是什么意思?它有效,而且应该有效。你试过这个吗?有错误吗?对不起,我的意思是它是正确的。编译器中没有错误。但是,我想知道这样做是否正确。我的错。错误的框架。