I came across a lot of code in our company codebase with the following structure
class Base
{
public Base (var a, var b)
{
base_a = a;
base_b = b;
}
var base_a;
var base_b;
}
class Derived:Base
{
publc Derived (var a,b,c,d): base (a,d)
{
der_c = c;
der_d = d;
}
var der_c;
var der_d;
var der_e;
}
class Ref
{
Base _ref;
public Ref( var a,b,c,d)
{
_ref = new Derived (a,b,c,d)
}
public void method( )
{
_ref.der_e = 444; // won't compile
}
}
初始化der_e的正确方法是什么?具有基类引用和使用_ref的对象派生类有什么好处?只是使用基类引用可以容纳多个派生类对象的事实?如果是这种情况,那么派生类的所有成员变量是否应该在构造过程中初始化(如下所示:_ref = new Derived(a,b,c,d))。如果我想稍后在方法中初始化_ref.der_e怎么办?我知道我可以这样做(var cast_ref = _ref为Derived; cast_ref.der_e = 444)但这看起来似乎不是最好的做法。有这样一个结构的想法是什么,以及在构造派生类对象的成员之后初始化它的正确性是什么?
答案 0 :(得分:0)
单个帖子中的问题太多了。
初始化der_e的正确方法是什么?
对于初始化der_e
,您必须具有Derived
类的引用,因为它知道der_e属性而不是Base
类。
拥有基类和使用的引用有什么好处 _ref?
的对象派生类
是的,这叫做Polymorphism,这是面向对象编程的本质。它允许我们在不知道实际实现的情况下持有各种具体实现。
如果是这样的话,应该是派生类的所有成员变量 在施工期间进行初始化(如下所示:_ref = new 派生(a,b,c,d))
没有这样的规则。这取决于您的情况。如果在创建对象后不打算更改这些值,并且在构造对象期间预先知道这些值,那么它们应该在构造期间初始化。
再次,如果有各种情况,例如有时值已知,有时不知道,则可能存在重载构造函数,它们采用不同的参数。
如果我想稍后在方法中初始化_ref.der_e怎么办?
这完全没问题,这取决于你想要实现的目标。这个问题不是具体的问题,而是一个抽象问题,很难对你想要实现的目标发表评论。
我知道我可以这样做(var cast_ref = _ref为Derived; cast_ref.der_e = 444)但这看起来似乎不是最好的做法。
我正在分享一些类似于C#的Java代码,因为我来自Java背景
//This class knows about Base and nothing about the Derived class
class UserOfBase{
Base ref;
//Constructor of UserOfBase gets passed an instance of Base
public UserOfBase(Base bInstance){
this.ref = bInstance;
}
//Now this class should not cast it into Derived class as that would not be a polymorphic behavior. In that case you have got your design wrong.
public void someMethod(){
Derived derivedRef = (Derived)ref; //This should not happen here
}
}
我正在分享一些可以帮助你的参考文献,因为我认为答案可能需要很长时间来解释。
答案 1 :(得分:0)
您可以在派生类中创建构造函数并映射对象或创建扩展方法,如下所示:
public static class Extensions
{
public static void FillPropertiesFromBaseClass<T1, T2>(this T2 drivedClass, T1 baseClass) where T2 : T1
{
//Get the list of properties available in base class
System.Reflection.PropertyInfo[] properties = typeof(T1).GetProperties();
properties.ToList().ForEach(property =>
{
//Check whether that property is present in derived class
System.Reflection.PropertyInfo isPresent = drivedClass.GetType().GetProperty(property.Name);
if (isPresent != null && property.CanWrite)
{
//If present get the value and map it
object value = baseClass.GetType().GetProperty(property.Name).GetValue(baseClass, null);
drivedClass.GetType().GetProperty(property.Name).SetValue(drivedClass, value, null);
}
});
}
}
例如,当您必须像这样上课时:
public class Fruit {
public float Sugar { get; set; }
public int Size { get; set; }
}
public class Apple : Fruit {
public int NumberOfWorms { get; set; }
}
您可以通过以下代码初始化派生类:
//constructor
public Apple(Fruit fruit)
{
this.FillPropertiesFromBaseClass(fruit);
}