Mik*_*uel 15
子类化是一种子类型.
Java允许子类型化的方式有很多种:
class A extends B,A是B因为B b = new A(...);是好的子类型.interface A extends B,A是B因为B b = new A() { ... }是好的子类型.class A extends B,A[]是B[]因为B[] b = new A[0]是好的子类型.class A implements B,A是B因为B b = new A(...)是好的子类型.听起来你想要一种方法来区分其他人.以下应该这样做.
static boolean isSubclass(Class<?> a, Class<?> b) {
return !b.isArray() && !b.isInterface() && b.isAssignableFrom(a);
}
Run Code Online (Sandbox Code Playgroud)
但是由于类型擦除,它不会处理泛型类的子类型. Class实例不会在运行时进行类型的参数,所以没有办法区分的运行时类型new ArrayList<String>()从new ArrayList<Integer>().
通常,子类化意味着继承父级的属性.子类型仅意味着可以对子类型执行超类型的操作.请注意,子类化是子类型的特例.
在Java中,接口表示用于描述类型可以表现出什么行为的结构,这使得它成为子类型的自然表示.子类化体现在类层次结构中.
小智 7
子类与子类型不同.您可以创建非子类型的子类.要了解子类型是什么,让我们开始解释类型是什么.
当我们说数字5是整数类型时,我们声明5属于一组可能的值(作为示例,请参阅Java原始类型的可能值).我们还指出,我可以对加值和减法等值执行一组有效的方法.最后我们说明有一组总是满足的属性,例如,如果我添加值3和5,我将得到8作为结果.
再举一个例子,想想抽象数据类型,整数集和整数的名单,他们能够保存的值被限制为整数.它们都支持一组方法,如add(newValue)和size().并且它们都具有不同的属性(类不变),集合不允许重复,而List允许重复(当然还有其他属性,它们都满足).
子类型也是一种类型,它与另一种类型有关系,称为父类型(或超类型).子类型必须满足父类型的特征(值,方法和属性).该关系意味着在期望超类型的任何上下文中,它可以由子类型替代,而不会影响执行的行为.我们来看看一些代码来举例说明我在说什么.假设我写了一个整数列表(用某种伪语言):
class List {
data = new Array();
Integer size() {
return data.length;
}
add(Integer anInteger) {
data[data.length] = anInteger;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我将整数集写为整数列表的子类:
class Set, inheriting from: List {
add(Integer anInteger) {
if (data.notContains(anInteger)) {
super.add(anInteger);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们的整数类集是整数列表的子类,但不是子类型,因为它不满足List类的所有功能.满足方法的值和签名,但属性不满足.add(Integer)方法的行为已经明确更改,而不是保留父类型的属性.从您的课程客户的角度思考.它们可能会收到一组整数,其中需要一个整数列表.客户端可能希望添加值并将该值添加到List中,即使该值已存在于List中.但如果价值存在,她就不会得到那种行为.对她来说太大了!
这是不正确使用继承的典型示例.在这种情况下使用组合.
(来自的片段:正确使用继承).
一次,维基百科给出了一个非常直接的答案:
http://en.wikipedia.org/wiki/Subtype_polymorphism
不应将子类型与面向对象语言的(类或对象)继承概念混淆; subtyping是类型之间的关系(面向对象的说法中的接口),而继承是源自语言特征的实现之间的关系,该特性允许从现有对象创建新对象.在许多面向对象的语言中,子类型称为接口继承.
简而言之,当你从另一个派生一个接口(方法签名/访问点/对外界做出反应的方式)时会发生子类型,而当你从一个类派生一个类的实现(方法,属性/内部状态和内部逻辑)时会发生子类化.通过继承的另一个类.
此术语通常不以这种方式使用,类型通常是指数据类型.