我在Output()
和Hour
类中的方法Day
中使用相同的代码。
有没有办法避免它在一个地方而不是两个地方改变代码?
class Program
{
static void Main(string[] args)
{
Hour hour = new Hour("20150715 080000");
Day day = new Day(hour);
Console.WriteLine(String.Format("Hour: {0}", hour.Output()));
Console.WriteLine(String.Format("Day: {0}", day.Output()));
}
}
public interface IMoment
{
string OutputMoment();
}
class Hour : IMoment
{
public string Date;
public string Time;
public Hour (string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
public string Output()
{
return Date + " " + Time;
}
}
class Day : IMoment
{
public string Date;
public string Time;
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
public string Output()
{
return Date + " " + Time;
}
}
答案 0 :(得分:6)
不要错误地创建基类来共享该方法。这是继承的常见滥用。这种技术一般会中断,你会在类的公共接口中引入一个无意义的类。 继承不适用于代码共享。适用于“Liskov替换”。
相反,创建一个静态辅助方法,它将两个值作为参数并计算结果。这允许您实现一次格式化。这很容易实现,几乎总是有效,并且不会影响类的公共API。不要害怕稍大的语法占用空间。这不是一个重大问题(大部分时间)。
答案 1 :(得分:1)
作为usr的答案的替代方案,您可以重构代码,以便将数据写入屏幕分开。
因此,您的Hour
和Day
课程不具备2项职责(单一责任原则),并且使代码更容易在未来使用更复杂的输出功能进行更新,因为您只需要更改writer类中的代码。 (或抽象它并创建例如FileMomentWriter
等)
public interface IMoment
{
string MomentType {get;}
string Date {get;set;}
string Time {get;set;}
}
public class Hour:IMoment
{
public string MomentType {get{return "Hour";}}
public string Date {get;set;}
public string Time {get;set;}
public Hour (string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
}
public class Day: IMoment
{
public string MomentType {get{return "Day";}}
public string Date{get;set;}
public string Time{get;set;}
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
}
public class ConsoleMomentWriter
{
public void Write(IMoment moment)
{
Console.WriteLine("{0}: {1} {2}",moment.MomentType,moment.Date,moment.Time);
}
}
class Program
{
static void Main(string[] args)
{
Hour hour = new Hour("20150715 080000");
Day day = new Day(hour);
var writer = new ConsoleMomentWriter();
writer.Write(hour);
writer.Write(day);
}
}
答案 2 :(得分:0)
您应该制作abstract class
而不是interface
:
class Program
{
static void Main(string[] args)
{
Hour hour = new Hour("20150715;080000");
Day day = new Day(hour);
Console.WriteLine(String.Format("Hour: {0}", hour.OutputMoment()));
Console.WriteLine(String.Format("Day: {0}", day.OutputMoment()));
}
}
public abstract class Moment
{
public string Date;
public string Time;
public virtual string OutputMoment()
{
return Date + " " + Time;
}
public override string ToString()
{
return OutputMoment();
}
}
class Hour : Moment
{
public Hour(string s)
{
string[] parts = s.Split(';');
this.Date = parts[0];
this.Time = parts[1];
}
}
class Day : Moment
{
public Day(Hour hour)
{
this.Date = hour.Date;
this.Time = hour.Time;
}
}
如果需要,将OutputMoment()
标记为virtual
也可以让您超越默认实施。我也覆盖了ToString()
,以便您可以执行Console.WriteLine(hour);
之类的操作而无需致电OutputMoment()
答案 3 :(得分:-1)
只是继承一个具有该公共成员的类:)
Promise.delay