Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么需要模板/泛型?Isn';继承还不够吗? 我听说很多人说C++模板非常强大。我似乎仍然不明白使用它们而不是使用继承的好处_Java_C++_Templates_Generics_Inheritance - Fatal编程技术网

Java 为什么需要模板/泛型?Isn';继承还不够吗? 我听说很多人说C++模板非常强大。我似乎仍然不明白使用它们而不是使用继承的好处

Java 为什么需要模板/泛型?Isn';继承还不够吗? 我听说很多人说C++模板非常强大。我似乎仍然不明白使用它们而不是使用继承的好处,java,c++,templates,generics,inheritance,Java,C++,Templates,Generics,Inheritance,由于我主要是一名Java开发人员,我认为泛型和模板是一回事,但相应地: 虽然C++模板、java泛型和.NET泛型通常被认为是相似的,但是泛型只模仿C++模板的基本行为。 我还想知道,在可能只使用类的地方使用模板是否会混淆代码?继承是不够的。考虑 STD::向量< /代码>(或者也许更相关, STD::向量< /代码>),作为例子。它在编译时为您提供了一个类型安全的容器类(对于任何T)。这在继承中是不可能的。如果您有一个类型不可知的方法,如(p-code) 您将如何正确地实施它lhs和rhs可能

由于我主要是一名Java开发人员,我认为泛型和模板是一回事,但相应地:

<>虽然C++模板、java泛型和.NET泛型通常被认为是相似的,但是泛型只模仿C++模板的基本行为。
我还想知道,在可能只使用类的地方使用模板是否会混淆代码?

继承是不够的。考虑<代码> STD::向量< /代码>(或者也许更相关,<代码> STD::向量< /代码>),作为例子。它在编译时为您提供了一个类型安全的容器类(对于任何
T
)。这在继承中是不可能的。

如果您有一个类型不可知的方法,如(p-code)

您将如何正确地实施它
lhs
rhs
可能是所有的东西,甚至不能保证两者都是同一类型的,所以如果你这样称呼它呢

add ("foo@example.com", 3)
add (std::vector<int>, std::pair<Foo, float>() )
add (add, add)
添加(“foo@example.com", 3)
添加(std::vector,std::pair())
添加(添加,添加)
?

使用模板/泛型,您可以是显式的(p代码)

模板
无效添加(参数类型lhs、参数类型rhs)
这也意味着您可以保护类型安全性

这只是多态性无法解决的众多例子之一。此外,泛型实际上与模板不同,因此实际上很难给出一个定制良好的答案

运行时调度(虚拟函数等)也总是要付出潜在的代价。专门的代码通过C++模板实例化只是为了你所说的,即不需要额外的性能成本。代码膨胀是可以忽略的,因为C++模板是懒惰地实例化的(只有你真正调用的是实际代码),而且字节数并不是用手动的(“重载”)代码多的。
<> > C++世界不仅仅是由OOP[-动态多态性]组成的,

< P>旧的,你会用:

 List myList = new ArrayList();
 myList.add(new String("Hello"));
 ....

 String myString = (String) myList.get(0);
如果在列表中插入不同类型的值,则只有在检索对象时才能找到,而没有关于真正失败的位置的信息(插入错误类型的对象)

现在,你要:

 List<String> myList = new ArrayList<String>();
List myList=new ArrayList();
错误被抛出错误所在的位置


这在“过去”已经得到了控制,但它涉及扩展ArrayList或创建包装器,以便只接受有效类;泛型大大简化了它。

模板出现在编译时。继承发生在运行时。您可以在编译时捕获模板中的错误,您必须对这些错误进行单元测试继承(然后希望不要错过它们)。此外,模板比继承更干净、更平滑

考虑一个简单的例子,在Java中是List。当你有一个列表,它应该只包含,我不知道,客户,但如果在现实中它包含了一堆对象引用,你不能保证它不包含一堆动物或数据库连接,当你得到它,你必须投,它可以扔。泛型保证正确的结果,无需强制转换。如果你写了一个bug试图在这里插入不属于你的东西,你的编译器会抛出一个错误。这种安全级别远远高于多态性所能提供的安全级别

此外,模板(在C++中)可以接受类型以外的参数,比如整数类型,可以执行编译时类型内省,等等。模板的可能性比继承的可能性大得多,而且更安全、更快

最后,对于模板,您不必显式继承。如果我想提供
操作符+
,是否必须从Addable继承?否,模板将自动拾取它。这比显式指定我可以继承的每个功能更易于维护,因为当出现新库时,我将不必更改代码以从其可添加接口继承。在C++中,我不必从可调用接口继承,允许使用<代码> Boo::函数< /> >,即使在编写了函数对象之后开发它。Java永远无法通过继承实现这一点。你怎么能开发一个没有泛型就可以处理变量数量的类呢?编写Callable1、Callable2、Callable3接口

考虑另一个简单的例子。假设我想把两个对象相加,然后用最后一个对象减去结果。如果你有一个IAddable接口,你怎么可能指定加法运算的结果是可减的呢?可以减去什么-我当然希望这不是另一个参数?您基本上必须为每个复杂的用例编写一个新的接口。另一方面,模板始终维护其类型信息,因此如果我执行的操作多于两个,结果不会丢失其信息


这些参数基本上与静态和动态类型相同,实际上,模板是静态的,继承是动态的。静态类型比动态类型快得多,也不容易出错。

模板和继承扮演不同的角色,这是相当罕见的 你可以从中选择。应该有一个非常简单的描述 模板为不同的应用程序提供了一个通用的实现 接口,其中as继承为 不同的实现。在通常的角色中,模板执行 编译时类型系统上的不变量;考虑一些 预模板库,其中
向量
只能包含
对象*
, 所有东西都必须从
对象
(你必须把东西框起来) 比如
int
)。插入
 List myList = new ArrayList();
 myList.add(new String("Hello"));
 ....

 String myString = (String) myList.get(0);
 List<String> myList = new ArrayList<String>();