返回信息流最近做代码重构的时候遇到了这样一个问题。尝试用如下代码描述一下
class Singer extends People{
@Override
public void talk(){
sing();
}
}
class Dancer extends People{
@Override
public void walk(){
dance();
}
}
现在我需要实现各种各样的People类:只会唱歌不会跳舞,只会跳舞不会唱歌,又会唱歌又会跳舞。目前的想法是再弄一个类:
class SingerDancer extends People{
@Override
public void talk(){
sing();
}
}
这样的问题在于,这个sing方法其实和singer中的sing方法是一模一样的,感觉代码复用上有点不和谐,强迫症,想解决。
这是一条镜像帖。来源:北邮人论坛 / java / #40961同步于 2015/5/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
关于JAVA实现类似多继承的疑问
hwz2311245
2015/5/22镜像同步19 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
似乎并没有那么简单。
我把示例复杂化了一下,因为目前实现功能必须重写父类方法。
相当于,会唱歌的人说话的时候就会唱歌,会跳舞的人走路的时候会跳舞。
【 在 limingji0503 的大作中提到: 】
: 组合?把唱歌和跳舞抽象成功能。有这个功能的人里面放个唱歌或者跳舞的实例。
singer 和 dancer 不要实现为people的子类,实现成接口
参考 装饰者模式
interface Singer{
public void sing(){}
}
interface Dancer{
public void dancer(){}
}
class SingerPeople extends People implements Singer{
@Override
public void talk(){
}
@Override
public void sing(){
}
}
class SingerDancer extends SingerPeople implements Dancer{
@Override
public void talk(){
}
@Override
public void sing(){
}
@Override
public void dance(){
}
}
【 在 hwz2311245 (【意涵团】Captain) 的大作中提到: 】
: 最近做代码重构的时候遇到了这样一个问题。尝试用如下代码描述一下
: class Singer extends People{
: @Override
: ...................
re ls。
接口就可以了吧。
或者就在不想实现的方法里面throw exception。@_@
【 在 hwz2311245 的大作中提到: 】
: 最近做代码重构的时候遇到了这样一个问题。尝试用如下代码描述一下
: class Singer extends People{
: @Override
: ...................
做成接口确实形式不错。
不过问题是接口并不能够实现具体功能。所以在子类之后还是要复制粘贴实现代码。
【 在 dss886 的大作中提到: 】
: singer 和 dancer 不要实现为people的子类,实现成接口
: 参考 装饰者模式
: [code=java]
: ...................
【 在 hwz2311245 的大作中提到: 】
: 做成接口确实形式不错。
: 不过问题是接口并不能够实现具体功能。所以在子类之后还是要复制粘贴实现代码。
:
package cn.byr.nuanyangyang.singsing;
interface HasName {
String getName();
}
interface Singer {
void sing();
}
interface Dancer {
void dance();
}
class GenericSingerImpl implements Singer {
@Override public void sing() { System.out.println("I sing."); }
}
class NamedDancerImpl implements Dancer {
private HasName thing;
public NamedDancerImpl(HasName thing) { this.thing = thing; }
@Override public void dance() {
System.out.println(thing.getName() + " dances.");
}
}
class Person implements HasName, Singer, Dancer {
private String name;
@Override public String getName() { return name; }
public Person(String name) { this.name = name; }
private GenericSingerImpl singerImpl = new GenericSingerImpl();
private NamedDancerImpl dancerImpl = new NamedDancerImpl(this);
@Override public void sing() { singerImpl.sing(); }
@Override public void dance() { dancerImpl.dance(); }
}
public class MixinTestJava {
public static void main(String[] args) {
Person p = new Person("Alice");
Singer s = p;
Dancer d = p;
s.sing();
d.dance();
}
}
但是试试Scala吧,下面这个程序和那个Java程序做同样的事情:
package cn.byr.nuanyangyang.singsingscala
trait HasName {
def name: String
}
trait Singer {
def sing(): Unit
}
trait Dancer {
def dance(): Unit
}
trait GenericSingerMixin extends Singer {
def sing(): Unit = { println("I sing") }
}
trait NamedDancerMixin extends HasName with Dancer {
def dance(): Unit = { println(name + " sing") }
}
class Person(val name: String) extends HasName with GenericSingerMixin with NamedDancerMixin {
// You don't need to write anything here. It just works.
}
object MixinTestScala extends App {
val p = new Person("Alice")
val s: Singer = p
val d: Dancer = p
s.sing()
d.dance()
}
不需要写两遍的,我可能说的不是很清楚
class SingerDancer extends SingerPeople implements Dancer{
@Override
public void dance(){
}
}
//这里调用sing()会调用父类(SingerPeople)的sing()
new SingerDancer().sing()
//这里调用talk()会调用父类的父类(People)的talk()
new SingerDancer().talk()
// talk()、sing()、dance()都只需要实现一遍,子类不override的话执行的是父类的代码
【 在 hwz2311245 的大作中提到: 】
: 做成接口确实形式不错。
: 不过问题是接口并不能够实现具体功能。所以在子类之后还是要复制粘贴实现代码。
:
赞一个~ 应该可以这么实现
PS: "You don't need to write anything here. It just works." 这个Scala的comments真是简单粗暴
【 在 nuanyangyang 的大作中提到: 】
:
: [code=java]
: package cn.byr.nuanyangyang.singsing;
: ...................