如果我们可以简单地覆盖超类的方法或使用抽象 类,为什么还要使用接口?
Why should we use interface if we can simply override methods of the superclass or use abstract classes?
我有两个程序,一个使用接口实现,另一个仅使用 classes 实现 -
我读过使用接口的优点是它可以提供它自己的 super class 方法的实现,但这可以使用抽象 classes 或方法覆盖来完成。接口的作用是什么?
在什么样的层次结构和情况下使用界面最有利?
界面
interface Shape
{
void area(int x, int y);
}
class Rectangle implements Shape
{
@Override
public void area(int length, int breadth)
{
System.out.println(length*breadth);
}
}
class Triangle implements Shape
{
@Override
public void area(int base, int height)
{
System.out.println(base*height);
}
}
public class ShapeUsingInterface
{
public static void main(String X[])
{
Rectangle r = new Rectangle();
Triangle t = new Triangle();
r.area(5, 4);
t.area(6, 3);
}
}
CLASS
class Shape
{
void Area(int x, int y)
{
System.out.println(x*y);
}
}
class Rectangle extends Shape
{
}
class Triangle extends Shape
{
@Override
void Area(int base, int height)
{
System.out.println((0.5)*base*height);
}
}
public class CalculateArea
{
public static void main(String X[])
{
Rectangle r = new Rectangle();
Triangle t = new Triangle();
r.Area(4, 5);
t.Area(6, 8);
}
}
接口定义契约。比如说:
interface MusicPlayer
{
public void shuffle();
}
现在每个 class 实现 接口都可以有自己的算法来实现 shuffle
方法,这取决于他们。抽象class类似于接口,抽象class定义几个方法普通,其他方法留给以我们自己的方式实施。喜欢
abstract class MusicPlayer
{
public void turnOff()
{
//kill the app
}
abstract public void shuffle();
}
使用接口,您可以实现多个接口,但只能扩展一个 class。
要解释为什么要使用接口,首先要明白一个继承的问题。它被称为 Diamond Problem。简单来说,如果一个class,D
继承自两个class,B
和C
,而B
和C
都继承来自同一个 class A
,D
得到了 A
中方法的哪个实现?
我们剩下的是方法歧义 Java 不喜欢!所以防止这种情况的方法是确保 D
只能 有一个 一个超级 class,这样它就可以继承自 A
, B
或 C
,但绝不会超过一个。这样就避免了这个问题,但是我们失去了多重继承提供的所有好处!
进入界面。这使我们能够享受多重继承的好处(将单个 class 引用为各种不同的类型)并且仍然避免菱形问题,因为实现 class 提供了方法。这消除了方法的歧义。
这意味着,例如:
public abstract class MyClass {
public void doSomething();
}
public class MyConcreteClass extends MyClass {
public void doSomething() {
// do something
}
}
您可以将 MyConcreteClass
的实例引用为
MyClass class = new MyConcreteClass();
或
MyConcreteClass class = new MyConcreteClass();
但鉴于此实现,没有别的。你不能 extend
更多 classes 因为你可能会遇到钻石问题,但你可以包含一个 Interface
public class MyConcreteClass extends MyClass implements Serializable {
}
突然间,你可以说..
Seralizable myClass = new MyConcreteClass();
因为myClass
是一个Serializable
。当一个方法可能不需要 知道 它是 MyConcreteClass
的一个实例时,这对于彼此解耦 class 非常有用,只需要知道它有一个必要的方法子集。
简而言之:你可以实现很多接口,但是你只能继承一个class.
您可以将 interface
s 视为一种社会契约,它规定所有实现接口的 classes 都应该定义接口中声明的方法。这在实现它们的所有 classes 之间创建了连续性,如果您希望所有这些 classes 具有相同的行为,那就太棒了。由于接口本身不声明实现,因此它将其留给实现它的 class 。通过这种方式,您可以创建许多机器,例如,它们都有一个开始按钮,您可能希望它们都拥有。更好的说法是 要求 他们都拥有,社会契约确保情况如此,因为您必须实现接口的每个方法!这是编译器要求的。
A class
覆盖了另一个 class 中的所有方法(通过扩展 class 并在其上实现)并没有真正说明它将永远如此信守承诺。知道 class 会忠诚的好处已经消失,你掩盖了它背后的逻辑。查看是否所有方法都被覆盖会不太清楚,这是不好的做法。为什么不把你的逻辑说清楚,实际用一个接口来实现社会契约。
Abstract classes 有点不同,因为它们也实现方法,正如普通 classes 所见,并且还作为接口工作,因为它们还要求您实现已声明但未实现的方法。 java8个接口也可以做到这一点。
我会说在你的例子中 Shape
绝对不应该是 class,而是接口。您已经为面积计算提供了默认实现 x*y
,但是在大多数形状的情况下,此实现不正确。
如果您要添加新形状,您将继承方法但实现不正确。您必须记住检查所有 classes 中的所有方法以验证继承的方法。在界面的情况下你不能犯这个错误。
我有两个程序,一个使用接口实现,另一个仅使用 classes 实现 -
我读过使用接口的优点是它可以提供它自己的 super class 方法的实现,但这可以使用抽象 classes 或方法覆盖来完成。接口的作用是什么?
在什么样的层次结构和情况下使用界面最有利?
界面
interface Shape
{
void area(int x, int y);
}
class Rectangle implements Shape
{
@Override
public void area(int length, int breadth)
{
System.out.println(length*breadth);
}
}
class Triangle implements Shape
{
@Override
public void area(int base, int height)
{
System.out.println(base*height);
}
}
public class ShapeUsingInterface
{
public static void main(String X[])
{
Rectangle r = new Rectangle();
Triangle t = new Triangle();
r.area(5, 4);
t.area(6, 3);
}
}
CLASS
class Shape
{
void Area(int x, int y)
{
System.out.println(x*y);
}
}
class Rectangle extends Shape
{
}
class Triangle extends Shape
{
@Override
void Area(int base, int height)
{
System.out.println((0.5)*base*height);
}
}
public class CalculateArea
{
public static void main(String X[])
{
Rectangle r = new Rectangle();
Triangle t = new Triangle();
r.Area(4, 5);
t.Area(6, 8);
}
}
接口定义契约。比如说:
interface MusicPlayer
{
public void shuffle();
}
现在每个 class 实现 接口都可以有自己的算法来实现 shuffle
方法,这取决于他们。抽象class类似于接口,抽象class定义几个方法普通,其他方法留给以我们自己的方式实施。喜欢
abstract class MusicPlayer
{
public void turnOff()
{
//kill the app
}
abstract public void shuffle();
}
使用接口,您可以实现多个接口,但只能扩展一个 class。
要解释为什么要使用接口,首先要明白一个继承的问题。它被称为 Diamond Problem。简单来说,如果一个class,D
继承自两个class,B
和C
,而B
和C
都继承来自同一个 class A
,D
得到了 A
中方法的哪个实现?
我们剩下的是方法歧义 Java 不喜欢!所以防止这种情况的方法是确保 D
只能 有一个 一个超级 class,这样它就可以继承自 A
, B
或 C
,但绝不会超过一个。这样就避免了这个问题,但是我们失去了多重继承提供的所有好处!
进入界面。这使我们能够享受多重继承的好处(将单个 class 引用为各种不同的类型)并且仍然避免菱形问题,因为实现 class 提供了方法。这消除了方法的歧义。
这意味着,例如:
public abstract class MyClass {
public void doSomething();
}
public class MyConcreteClass extends MyClass {
public void doSomething() {
// do something
}
}
您可以将 MyConcreteClass
的实例引用为
MyClass class = new MyConcreteClass();
或
MyConcreteClass class = new MyConcreteClass();
但鉴于此实现,没有别的。你不能 extend
更多 classes 因为你可能会遇到钻石问题,但你可以包含一个 Interface
public class MyConcreteClass extends MyClass implements Serializable {
}
突然间,你可以说..
Seralizable myClass = new MyConcreteClass();
因为myClass
是一个Serializable
。当一个方法可能不需要 知道 它是 MyConcreteClass
的一个实例时,这对于彼此解耦 class 非常有用,只需要知道它有一个必要的方法子集。
简而言之:你可以实现很多接口,但是你只能继承一个class.
您可以将 interface
s 视为一种社会契约,它规定所有实现接口的 classes 都应该定义接口中声明的方法。这在实现它们的所有 classes 之间创建了连续性,如果您希望所有这些 classes 具有相同的行为,那就太棒了。由于接口本身不声明实现,因此它将其留给实现它的 class 。通过这种方式,您可以创建许多机器,例如,它们都有一个开始按钮,您可能希望它们都拥有。更好的说法是 要求 他们都拥有,社会契约确保情况如此,因为您必须实现接口的每个方法!这是编译器要求的。
A class
覆盖了另一个 class 中的所有方法(通过扩展 class 并在其上实现)并没有真正说明它将永远如此信守承诺。知道 class 会忠诚的好处已经消失,你掩盖了它背后的逻辑。查看是否所有方法都被覆盖会不太清楚,这是不好的做法。为什么不把你的逻辑说清楚,实际用一个接口来实现社会契约。
Abstract classes 有点不同,因为它们也实现方法,正如普通 classes 所见,并且还作为接口工作,因为它们还要求您实现已声明但未实现的方法。 java8个接口也可以做到这一点。
我会说在你的例子中 Shape
绝对不应该是 class,而是接口。您已经为面积计算提供了默认实现 x*y
,但是在大多数形状的情况下,此实现不正确。
如果您要添加新形状,您将继承方法但实现不正确。您必须记住检查所有 classes 中的所有方法以验证继承的方法。在界面的情况下你不能犯这个错误。