【发布时间】:2011-09-01 20:03:35
【问题描述】:
在 Java 中,一个类只能从一个类继承,但它可以实现 不止一个接口。因此,对象可以有多种类型: 他们自己的类的类型和所有接口的类型 他们实施。这意味着如果一个 变量被声明为 接口的类型,它的值可以引用任何对象 从任何实现接口的类实例化。
谁能为此提供一个基本的伪类型。我没看懂粗线。
【问题讨论】:
在 Java 中,一个类只能从一个类继承,但它可以实现 不止一个接口。因此,对象可以有多种类型: 他们自己的类的类型和所有接口的类型 他们实施。这意味着如果一个 变量被声明为 接口的类型,它的值可以引用任何对象 从任何实现接口的类实例化。
谁能为此提供一个基本的伪类型。我没看懂粗线。
【问题讨论】:
让我们声明两个接口和一个实现它们的类:
interface I1 { }
interface I2 { }
class C implements I1, I2 { }
对象可以有多种类型
在下面的代码中,可以看出C实例的类型为C,还有I1和I2:
C c = new C();
boolean isC = (c instanceof C); //true
boolean isI1 = (c instanceof I1); //true
boolean isI2 = (c instanceof I2); //true
现在让我们声明一个类B,它也实现了I1:
class B implements I1 { }
如果一个变量被声明为接口的类型,它的值可以引用从任何实现该接口的类实例化的任何对象。
如果我们声明一个I1类型的变量,我们可以将其设置为C的实例,然后将其重新赋值给B的实例:
I1 i1 = new C();
i1 = new B();
我们还可以将它重新分配给D 的一个实例,其中D 扩展了C:
i1 = new D();
...
class D extends C { }
【讨论】:
考虑以下示例:
Serializable s = new ArrayList();
在 Java 中,这是有效的代码,即使 Serializable 是一个接口,因为 ArrayList 实现了 Serializable。所以在这种情况下,我们将s 视为Serializable 类型的变量。
现在假设我们用以下代码跟进上面的代码:
s = "String object";
这也是有效的,因为String 也实现了Serializable。由于我们将s 声明为Serializable 类型,它可以指向实现该接口的任何 对象。
【讨论】:
对象可以有多种类型
考虑以下 sn-p:
public class MyClass extends ParentClass implements Interface1, Interface2 {
//some code
}
这个类可以用在不同的地方,如下:
MyClass m1 = new MyClass();
ParentClass p = new MyClass();
Interface1 i1 = new MyClass();
Interface2 i2 = new MyClass();
变量被声明为接口的类型,它的值可以引用从任何实现该接口的类实例化的任何对象。
考虑前面sn-p的最后两行,Interface1类型的变量可以引用任何实现这个接口的对象,所以如果我们有另一个类实现了Interface1,比如MyClass2,那么
Interface1 i1 = new MyClass();
Interface1 i2 = new MyClasss2();
i1 = i2;
i1 = new MyClass2();
前面的所有赋值都是有效的,因为 MyClass 和 MyClass2 实现了 Interface1
【讨论】:
class Ball extends Rubber implements Jumping, Rolling, Squeezing {
public void jump(){}
public void roll(){}
public void squeeze(){}
}
Ball b = new Ball();
Jumping j = new Ball();
j.jump();
//j.roll(); //CTE: Cannot resolve method roll()
((Ball) j).roll(); //but it still can be called if explicit cast to type Ball is used
【讨论】:
String实现了多个接口,所以它有多种类型:
String s = "A String";
Comparable<String> comp = s;
CharSequece cs = s;
Serializable ser = s;
接口CharSequence由多个类实现,所以一个CharSequence引用可以容纳各种对象:
CharSequence cs = "A String";
cs = new StringBuilder();
cs = new Segment();
【讨论】:
对象可以有多种类型
例子:
public class Foo implements Runnable, Callable<Integer> {
public void run() {}
public Integer call() {return 1;}
}
Foo foo = new Foo();
Runnable r = foo;
Callable<Integer> c = foo;
例子:
如果一个变量被声明为接口的类型,它的值可以引用从任何实现该接口的类实例化的任何对象
Runnable r = new Foo();
r = Thread.currentThread(); //Thread implements Runnable
【讨论】:
您引用的陈述(从哪里来?)是真实的,但具有误导性——对象已经有多种类型而没有接口。
例如,"bimmelim" 具有 String 类型,但它也具有 Object 类型。接口不会改变这一点,除了"bimmelim" 也 具有Serializable、CharSequence 和其他类型。
实际上,我们是否应该说"bimmelim"“具有”类型Object 可能是有争议的,但对它的引用肯定会适合Object 变量。 p>
如果一个变量被声明为接口的类型……例如
CharSequence x ;
...那么它的值可以引用String 对象,例如"bimmelim",也可能是StringBuffer,这是实现CharSequence 的另一种类型。
【讨论】:
以下是正确的分配:
class AClass implements AInterface {
}
AInterface var = new AClass();
【讨论】:
非常基本的例子-
List<String> list1=new ArrayList<String>();
由于ArrayList实现了List,因此我们可以使用List接口变量,即list1来引用Arraylist创建的对象。
【讨论】:
考虑以下类和接口定义:
public class A { }
public class B extends A implements I { }
public interface I { }
以下陈述均合法:
A first = new A();
B second = new B();
A third = new B();
I fourth = new B();
因为 B 实现了 I 并扩展了 A,所以它可以用作任何需要“I”或“A”的值。
【讨论】:
以标准 Java 库中的Collection 接口为例。任何声明为Collection 类型的变量都可以被分配一个实现Collection 接口的类的对象,例如ArrayList, Stack, ...有关更多示例,请参阅链接文档。
【讨论】: