Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 如何用更具体的对象族(A';<;:A有许多B';<;:B)扩展对象族(A有许多B)?_Java_Oop_Types - Fatal编程技术网

Java 如何用更具体的对象族(A';<;:A有许多B';<;:B)扩展对象族(A有许多B)?

Java 如何用更具体的对象族(A';<;:A有许多B';<;:B)扩展对象族(A有许多B)?,java,oop,types,Java,Oop,Types,很抱歉这个标题太糟糕了,但我想不出更好的措辞了。我将尝试用一个例子来更清楚地说明这一点(这不是我实际上试图解决的问题,但我不想深入到具体问题的细节) 假设我想模拟论坛式的讨论。通常,一个主题代表要讨论的内容(一条消息、一张照片等),而评论则代表人们对该主题的评论。因此,在非常抽象的层面上,我们有: Topic + title + comments: List<Comment> Comment + text 最后,虽然Topic和AuthoredTopic可能最终成为接

很抱歉这个标题太糟糕了,但我想不出更好的措辞了。我将尝试用一个例子来更清楚地说明这一点(这不是我实际上试图解决的问题,但我不想深入到具体问题的细节)

假设我想模拟论坛式的讨论。通常,一个主题代表要讨论的内容(一条消息、一张照片等),而评论则代表人们对该主题的评论。因此,在非常抽象的层面上,我们有:

Topic
  + title
  + comments: List<Comment>

Comment
  + text
最后,虽然
Topic
AuthoredTopic
可能最终成为接口或抽象类,但如果对于像
YouTubeVideoTopic
这样的具体类,可以向它们添加注释(其
addComment
方法应该接收一个YouTubeComment参数),那就太好了

现在我将解释我为解决这个问题而尝试的两种方法,它们都不是真正成功或令人信服的

方法1:使用多个方法返回注释 基本的topic类有一个抽象的
getComments:List
方法,而AuthoredTopic类添加了一个抽象的
getAuthoredComments:List
方法,最后像YouTubeVideoTopic这样的叶类有一个具体的
getYouTubeComments:List
,同时还实现了它们的父类的get*Comments方法

代码:

抽象类主题{
私有字符串标题;
公共主题(字符串标题){
this.title=标题;
}
公共摘要列表getComments();
//其他获得者。。。
}
课堂评论{
私有字符串文本;
//构造函数和getter
}
抽象类AuthoredTopic扩展了主题{
私有字符串作者;
公共AuthoredTopic(字符串标题、字符串作者){
超级(标题);
this.author=作者;
}
公共摘要列表getAuthoredComments();
@凌驾
公共列表getComments(){
返回集合。不可修改列表(getAuthoredComments());
}
}
类AuthoredComment扩展了注释{
私有字符串作者;
}
类YouTubeVideoTopic扩展了AuthoredTopic{
整数票;
字符串视频;//是的..“视频”现在是字符串。。。
列表注释=新建ArrayList();
公共YouTubeVideoTopic(字符串标题、字符串作者){
超级(标题、作者);
}
公共列表getYouTubeComments(){
返回集合。不可修改列表(注释);
}
@凌驾
公共列表getAuthoredComments(){
返回集合。不可修改列表(注释);
}
public void addComment(YouTubeComment comment){
注释。添加(注释);
}
}
类YouTubeComment扩展AuthoredComment{
整数票;
}
它完成了任务,但正如你所看到的,这是一个相当丑陋的解决方案。不是很干。像YouTubeVideoTopic这样的叶类必须实现很多东西。此外,嵌套的主题子类最终会有多个get*注释,这些注释只是设计中的噪音

方法2:添加泛型类型参数 我发现这种方法更容易实施:

课程主题{
私有字符串标题;
私有列表注释=新建ArrayList();
公共主题(字符串标题){
this.title=标题;
}
公共列表getComments(){
返回集合。不可修改列表(注释);
}
public void addComment(CommentT comment){
注释。添加(注释);
}
}
课堂评论{
私有字符串文本;
//构造函数和getter
}
类AuthoredTopic扩展
话题{
字符串作者;
公共AuthoredTopic(字符串标题、字符串作者){
超级(标题);
this.author=作者;
}
公共字符串getAuthor(){
返回作者;
}
}
类AuthoredComment扩展了注释{
私有字符串作者;
}
类YouTubeVideoTopic扩展了AuthoredTopic{
整数票;
字符串视频;//是的..“视频”现在是字符串。。。
公共YouTubeVideoTopic(字符串标题、字符串作者){
超级(标题、作者);
}
}
类YouTubeComment扩展AuthoredComment{
整数票;
}
但是,它的缺点是类型参数“泄漏”到使用此分类的代码中,即使通配符可以使字符开销非常小:

List<Topic<?>> t = getAllTopics();

List只需使用
getComments
方法返回
List这就是所谓的并行层次结构。会议进行了很好的讨论。谷歌搜索也带来了好东西


我同意基于泛型的方法更干净

谢谢你给“授权”起个更好的名字!但是我不太喜欢这个解决方案,因为
Topic
的派生类会有两个不同的列表:一个是基类的注释,另一个是派生类的AuthoredComments,尽管前一个列表不会用于任何用途。耸耸肩你似乎在问一个关于
Topic
泛化的方法,这是做这件事的方法
Topic
可以封装
列表,但是
AuthoredTopic
知道它们的注释是
AuthoredComments
。我正在寻找一种类型安全的解决方案,这样主题子类就不需要对其注释的类型做任何假设。
YouTubeVideoTopic < AuthoredTopic
  + video
  + votes
  + comments: List<YouTubeComment>

YouTubeComment < AuthoredComment
  + votes
List<Topic<?>> t = getAllTopics();
public class Topic {
    public List<? extends Comment> getComments() {
        return new ArrayList<Comment>();
    }
}

public class Comment {

}

public class AuthoredTopic extends Topic {

    @Override
    public List<? extends Comment> getComments() {
        return new ArrayList<AuthoredComment>();
    }
}

public class AuthoredComment extends Comment {

}