java 是否继承_java-是否可以在没有继承的情况下进行多态?

我读过的关于该主题的最好的解释是著名的类型理论家Luca Cardelli的一篇文章。 本文的名称为“了解类型,数据抽象和多态性”。

多态性的类型

Cardelli在本文中定义了几种类型的多态性:

普遍参数

包含

特设超载

强迫

与继承相关的多态性的种类分为包含多态性或亚型多态性。

维基百科提供了一个很好的定义:

在面向对象的编程中,子类型多态或包含   多态性是类型理论中的一个概念,其中名称可以表示   许多不同类的实例,只要它们通过   一些常见的超级类。 包含多态性通常是   通过子类型支持,即,不同类型的对象是   完全可以替代另一种类型的对象(它们的基础   类型),因此可以通过通用接口进行处理。   或者,可以通过类型实现包含多态性   强制转换,也称为类型转换。

Wikipedia上另一篇名为“面向对象编程中的多态性”的文章似乎也回答了您的问题。

在Java中

Java中的这种子类型化功能是通过继承类和接口来实现的。 尽管Java的子类型功能可能在继承方面并不总是很明显。 以与泛型的协方差和逆方差为例。 另外,数组在序列层次结构中的任何地方都不明显,尽管它们是可序列化和可克隆的。 也可以说,通过原始扩展转换,Java中的数字运算符是多态的,在某些情况下甚至可以接受完全不相关的操作数(即字符串和数字或字符串加上其他对象的串联)。 还应考虑对基元进行装箱和拆箱的情况。 后面的多态情况(强制和重载)与继承完全无关。

例子

包容性

List myInts = new ArrayList();

您的问题似乎是在这种情况下引用的,即类型之间存在继承或实现关系时,例如在ArrayList实现List的情况下。

但是,正如我提到的,当您引入Java泛型时,子类型化的规则有时会变得模糊:

List super Number> myObjs = new ArrayList();

List extends Number> myNumbers = new LinkedList();

在其他情况下,API中的关系甚至都不明显

Cloneable clone = new int[10];

Serializable obj = new Object[10]

即使如此,根据Cardelli所说,所有这些都是通用多态性的形式。

参数

public List filter(Predicate predicate, List source) {

List result = new ArrayList<>();

for(T item : source) {

if(predicate.evaluate(item)){

result.add(item);

}

return result;

}

}

可以使用相同的算法来过滤具有各种谓词的所有列表,而不必为每种可能的列表类型重复一行代码。 实际列表的类型和谓词的类型是参数性的。 请参阅此示例,其中包含JDK 8 Preview中可用的lambda表达式(为简化谓词实现)。

filter(x -> x % 2 == 0, asList(1,2,3,4,5,6)); //filters even integers

filter(x -> x % 2 != 0, asList(1L,2L,3L,4L,5L,6L)); //filters odd longs

filter(x -> x >= 0.0, asList(-1.0, 1.0)); //filters positive doubles

根据Cardelli的说法,这是通用多态性的一种形式。

强迫

double sum = 1 + 2.0;

整数和浮点算法完全不同。 如果没有某种形式的强制,将加号运算符应用于两个不同类型的操作数是不可能的。

在此示例中,整数和双精度类型将自动强制(转换)为双精度类型,而无需显式强制转换。 整个表达式提升为两倍。 之所以如此,是因为在Java中,我们有原始的扩展转换。

根据Cardelli的说法,这种自动强制形式是为plus运算符提供的即席多态形式。

在某些语言中,如果没有显式强制转换,您甚至无法将整数和浮点数相加(即AFAIK,SML,顺便说一下,参数多态性是克服此类问题的关键)。

超载

double sum = 2.0 + 3.0;

String text = "The sum is" + sum;

根据所使用的参数,加号运算符在这里表示两种不同的含义。 显然,操作员已经超负荷工作。 这意味着根据操作数的类型,它具有不同的实现。 根据Cardelli的说法,这是为plus运算符提供的一种即席多态形式。

当然,这也适用于类中方法重载的形式(即java.lang.Math方法min和max被重载以支持不同的原始类型)。

用其他语言

即使继承在其中某些形式的多态性的实现中起着重要作用,当然也不是唯一的方法。 其他非面向对象的语言提供其他形式的多态性。 例如,以动态语言(如Python)或静态类型的语言(如Go)键入鸭子的情况,或以SML,Ocaml和Scala等语言的代数数据类型,或以Haskell语言的类型类,在Clojure中使用多方法的情况 ,JavaScript中的原型继承等。

你可能感兴趣的:(java,是否继承)