为什么在具体装饰器的构造函数中我必须重复超类构造函数的代码?
Why in the concrete decorator's constructor I have to repeat code of the superclass constructor?
正在尝试实现装饰器模式 - 为了简单起见,在这个例子中我们只有 1 个名为 ConcreteDecorator1 的具体装饰器,我让它工作,这个例子是功能性的。但是我的问题是关于 OOP 的,更具体地说,我不明白为什么我在 ConcreteDecorator1 的这一行上得到一个“组件为空”的异常:myField = this.myField + component.Operation();
在相同的构造函数中添加 this.component = component
之前class?
我的意思是 this.component = component
发生在超级 class(装饰器)的 c-tor 中,那为什么还不够?
class Program
{
static void Main(string[] args)
{
var cc = new ConcreteComponent();
cc.Operation();
Console.WriteLine(cc.myField);
var cd1 = new ConcreteDecorator1(cc);
cd1.Operation();
Console.WriteLine(cd1.myField);
var cd2 = new ConcreteDecorator1(cd1);
cd2.Operation();
Console.WriteLine(cd2.myField);
Console.ReadLine();
}
}
abstract class Component
{
public int myField;
public virtual int Operation()
{
return myField;
}
}
class ConcreteComponent : Component
{
public override int Operation()
{
myField = 22;
return myField;
}
}
class Decorator : Component
{
private Component component;
public Decorator(Component component)
{
this.component = component;
}
}
class ConcreteDecorator1 : Decorator
{
private Component component;
public ConcreteDecorator1(Component component) : base(component)
{
this.component = component; // WHY IS THIS LINE NECESSARY HERE? Don't we have it in the constructor of the base class, Decorator?
}
public override int Operation()
{
myField = 100;
myField = this.myField + component.Operation(); // error on this line: component was null ... UNLESS WE ADD this.component = component; in the c-tor WHy was this necessary? Doesn't the super class c-tor take care of it?
return myField;
}
}
所以底线:为什么在具体装饰器的构造函数中我必须重复 superclass 构造函数的代码?我以为我可以这样保留它:
public ConcreteDecorator1(Component component) : base(component)
{
}
并可能在正文中添加一些额外的东西,比如额外的逻辑,如果需要的话(这里不需要,只是说)。
稍后编辑 - 另一个工作变体(变体 2):
class Program
{
static void Main(string[] args)
{
var cc = new ConcreteComponent();
cc.Operation();
Console.WriteLine(cc.myField);
var cd1 = new ConcreteDecorator1(cc);
cd1.Operation();
Console.WriteLine(cd1.myField);
var cd2 = new ConcreteDecorator1(cd1);
cd2.Operation();
Console.WriteLine(cd2.myField);
}
}
abstract class Component
{
public int myField;
public virtual int Operation()
{
return myField;
}
}
class ConcreteComponent : Component
{
public override int Operation()
{
myField = 22;
return myField;
}
}
class Decorator : Component
{
public Component Component { get; set; }
}
class ConcreteDecorator1 : Decorator
{
public ConcreteDecorator1(Component component)
{
this.Component = component;
}
public override int Operation()
{
myField = 100;
myField = this.myField + this.Component.Operation();
return myField;
}
}
仍然不太好,因为我宁愿在装饰器中定义操作,而在具体装饰器中我只设置 myField 值...
变体 3(稍后更新,也有效):
abstract class Component
{
protected int myField;
public virtual int Operation()
{
return this.myField;
}
}
class ConcreteComponent : Component
{
public ConcreteComponent(int myField)
{
this.myField = myField;
}
}
class Decorator : Component
{
protected Component component;
public Decorator(Component component)
{
this.component = component;
}
public override int Operation()
{
this.myField = this.myField + component.Operation();
return myField;
}
}
class ConcreteDecorator1 : Decorator
{
public ConcreteDecorator1(Component component) : base(component)
{
this.myField = 100;
}
}
class ConcreteDecorator2 : Decorator
{
public ConcreteDecorator2(Component component) : base(component)
{
this.myField = 1000;
}
}
class Program
{
static void Main(string[] args)
{
var cc = new ConcreteComponent(22);
Console.WriteLine(cc.Operation());
//var cd1 = new ConcreteDecorator(cc, 100);
//cd1.Operation();
//Console.WriteLine(cd1.myField);
var cd2 = new ConcreteDecorator1(cc);
Console.WriteLine(cd2.Operation());
var cd3 = new ConcreteDecorator2(cd2);
Console.WriteLine(cd3.Operation());
Console.ReadLine();
}
}
您不必重新定义通用对象private Component component;
。修改component的double定义如下
class Decorator : Component
{
public Component component;
public Decorator(Component component)
{
this.component = component;
}
}
class ConcreteDecorator1 : Decorator
{
public ConcreteDecorator1(Component component) : base(component)
{
}
public override int Operation()
{
myField = 100;
myField = this.myField + component.Operation(); // error on this line: component was null ... UNLESS WE ADD this.component = component; in the c-tor WHy was this necessary? Doesn't the super class c-tor take care of it?
return myField;
}
}
使用此代码,您只需设置父 class 的组件,而不是此 class 的组件。而这段代码执行时myField = this.myField + component.Operation ();
程序报空错误
public ConcreteDecorator1(Component component) : base(component)
{
//This is wrong because the component is never set
}
假设您有两个名为 x 的变量。您可以在函数中全局定义一个,并在本地定义另一个。访问全局变量时必须使用此关键字。
看这个例子:
static void Main(string[] args)
{
math m = new math();
m.cc();
m.dd();
}
class math
{
private int x = 100;
public int pp(out int disX)
{
int x = 200;
disX = this.x;
return x;
}
public void cc()
{
int x = 50;
Console.WriteLine(x); //answer: 50
Console.WriteLine(this.x); //answer: 100
}
public void dd()
{
int t;
Console.WriteLine(pp(out t)); // answer: 200
Console.WriteLine(t); //answer: 100
}
}
正在尝试实现装饰器模式 - 为了简单起见,在这个例子中我们只有 1 个名为 ConcreteDecorator1 的具体装饰器,我让它工作,这个例子是功能性的。但是我的问题是关于 OOP 的,更具体地说,我不明白为什么我在 ConcreteDecorator1 的这一行上得到一个“组件为空”的异常:myField = this.myField + component.Operation();
在相同的构造函数中添加 this.component = component
之前class?
我的意思是 this.component = component
发生在超级 class(装饰器)的 c-tor 中,那为什么还不够?
class Program
{
static void Main(string[] args)
{
var cc = new ConcreteComponent();
cc.Operation();
Console.WriteLine(cc.myField);
var cd1 = new ConcreteDecorator1(cc);
cd1.Operation();
Console.WriteLine(cd1.myField);
var cd2 = new ConcreteDecorator1(cd1);
cd2.Operation();
Console.WriteLine(cd2.myField);
Console.ReadLine();
}
}
abstract class Component
{
public int myField;
public virtual int Operation()
{
return myField;
}
}
class ConcreteComponent : Component
{
public override int Operation()
{
myField = 22;
return myField;
}
}
class Decorator : Component
{
private Component component;
public Decorator(Component component)
{
this.component = component;
}
}
class ConcreteDecorator1 : Decorator
{
private Component component;
public ConcreteDecorator1(Component component) : base(component)
{
this.component = component; // WHY IS THIS LINE NECESSARY HERE? Don't we have it in the constructor of the base class, Decorator?
}
public override int Operation()
{
myField = 100;
myField = this.myField + component.Operation(); // error on this line: component was null ... UNLESS WE ADD this.component = component; in the c-tor WHy was this necessary? Doesn't the super class c-tor take care of it?
return myField;
}
}
所以底线:为什么在具体装饰器的构造函数中我必须重复 superclass 构造函数的代码?我以为我可以这样保留它:
public ConcreteDecorator1(Component component) : base(component)
{
}
并可能在正文中添加一些额外的东西,比如额外的逻辑,如果需要的话(这里不需要,只是说)。
稍后编辑 - 另一个工作变体(变体 2):
class Program
{
static void Main(string[] args)
{
var cc = new ConcreteComponent();
cc.Operation();
Console.WriteLine(cc.myField);
var cd1 = new ConcreteDecorator1(cc);
cd1.Operation();
Console.WriteLine(cd1.myField);
var cd2 = new ConcreteDecorator1(cd1);
cd2.Operation();
Console.WriteLine(cd2.myField);
}
}
abstract class Component
{
public int myField;
public virtual int Operation()
{
return myField;
}
}
class ConcreteComponent : Component
{
public override int Operation()
{
myField = 22;
return myField;
}
}
class Decorator : Component
{
public Component Component { get; set; }
}
class ConcreteDecorator1 : Decorator
{
public ConcreteDecorator1(Component component)
{
this.Component = component;
}
public override int Operation()
{
myField = 100;
myField = this.myField + this.Component.Operation();
return myField;
}
}
仍然不太好,因为我宁愿在装饰器中定义操作,而在具体装饰器中我只设置 myField 值...
变体 3(稍后更新,也有效):
abstract class Component
{
protected int myField;
public virtual int Operation()
{
return this.myField;
}
}
class ConcreteComponent : Component
{
public ConcreteComponent(int myField)
{
this.myField = myField;
}
}
class Decorator : Component
{
protected Component component;
public Decorator(Component component)
{
this.component = component;
}
public override int Operation()
{
this.myField = this.myField + component.Operation();
return myField;
}
}
class ConcreteDecorator1 : Decorator
{
public ConcreteDecorator1(Component component) : base(component)
{
this.myField = 100;
}
}
class ConcreteDecorator2 : Decorator
{
public ConcreteDecorator2(Component component) : base(component)
{
this.myField = 1000;
}
}
class Program
{
static void Main(string[] args)
{
var cc = new ConcreteComponent(22);
Console.WriteLine(cc.Operation());
//var cd1 = new ConcreteDecorator(cc, 100);
//cd1.Operation();
//Console.WriteLine(cd1.myField);
var cd2 = new ConcreteDecorator1(cc);
Console.WriteLine(cd2.Operation());
var cd3 = new ConcreteDecorator2(cd2);
Console.WriteLine(cd3.Operation());
Console.ReadLine();
}
}
您不必重新定义通用对象private Component component;
。修改component的double定义如下
class Decorator : Component
{
public Component component;
public Decorator(Component component)
{
this.component = component;
}
}
class ConcreteDecorator1 : Decorator
{
public ConcreteDecorator1(Component component) : base(component)
{
}
public override int Operation()
{
myField = 100;
myField = this.myField + component.Operation(); // error on this line: component was null ... UNLESS WE ADD this.component = component; in the c-tor WHy was this necessary? Doesn't the super class c-tor take care of it?
return myField;
}
}
使用此代码,您只需设置父 class 的组件,而不是此 class 的组件。而这段代码执行时myField = this.myField + component.Operation ();
程序报空错误
public ConcreteDecorator1(Component component) : base(component)
{
//This is wrong because the component is never set
}
假设您有两个名为 x 的变量。您可以在函数中全局定义一个,并在本地定义另一个。访问全局变量时必须使用此关键字。
看这个例子:
static void Main(string[] args)
{
math m = new math();
m.cc();
m.dd();
}
class math
{
private int x = 100;
public int pp(out int disX)
{
int x = 200;
disX = this.x;
return x;
}
public void cc()
{
int x = 50;
Console.WriteLine(x); //answer: 50
Console.WriteLine(this.x); //answer: 100
}
public void dd()
{
int t;
Console.WriteLine(pp(out t)); // answer: 200
Console.WriteLine(t); //answer: 100
}
}