如何从其子类的实例初始化超类的属性?我还有更多问题

时间:2014-09-29 21:17:48

标签: c# oop

超级学生

namespace StudentPresentationGUI
{
    public class Student
    {
        public string name;
    }
}

子课程UnderGraduate

namespace StudentPresentationGUI
{
public class UnderGraduate : Student
{
    private string classification;
    private string guardianname;
    private string address;

    public UnderGraduate(string classif, string guardian, string addr)
    {
        classification = classif;
        guardianname = guardian;
        address = addr;
    }

    UnderGraduate()
    {

    }

    protected string getClassification()
    {
        return classification;
    }

    protected string getGuardianName()
    {
        return guardianname;
    }

    protected string getAddress()
    {
        return address;
    }

}}

让我说我实例化学生:

Student stud1 = new UnderGraduate("Senior", "mom", "New York");

问题:

  1. 如何使用字符串' name'超级类的名称在实例上' stud1'?

  2. 有什么区别(优点/缺点)

    Student stud1 = new UnderGraduate("Senior", "mom", "New York");
    

    UnderGraduatestud1 = new UnderGraduate("Senior", "mom", "New York");
    

    Student stud1 = new Student("Senior", "mom", "New York");
    

    第一次实例化我可以做什么,我不能在第二次和第三次实例化 反之亦然。

2 个答案:

答案 0 :(得分:0)

您需要(1)直接在子类构造函数中影响名称,或者在您的supperclass中创建一个构造函数并从子类中调用它:

选项(1):

namespace StudentPresentationGUI
{
    public class Student
    {
        public string name;
    }
}

/

namespace StudentPresentationGUI
{
public class UnderGraduate : Student
{
    private string classification;
    private string guardianname;
    private string address;

    //CHANGES HERE
    public UnderGraduate(string classif, string guardian, string addr, string _name) 
    {
        classification = classif;
        guardianname = guardian;
        address = addr;
        name = _name;
    }

    UnderGraduate()
    {

    }

    protected string getClassification()
    {
        return classification;
    }

    protected string getGuardianName()
    {
        return guardianname;
    }

    protected string getAddress()
    {
        return address;
    }

}}

选项(2):

namespace StudentPresentationGUI
{
    public class Student
    {
        public string name;
    }

    //CHANGES HERE
    public Student(string _name) 
    {
        name = _name;
    }
}

/

namespace StudentPresentationGUI
{
public class UnderGraduate : Student
{
    private string classification;
    private string guardianname;
    private string address;

    //CHANGES HERE (Look to the right)
    public UnderGraduate(string classif, string guardian, string addr, string _name) : base(_name) 
    {
        classification = classif;
        guardianname = guardian;
        address = addr;
    }

    UnderGraduate()
    {

    }

    protected string getClassification()
    {
        return classification;
    }

    protected string getGuardianName()
    {
        return guardianname;
    }

    protected string getAddress()
    {
        return address;
    }

}}

指令: base(_name)调用基类' (超类)构造函数,并将其_name作为参数值。

其他问题

问题1: 因为它是公共的,所以你只需要调用它,因为它是子类的一部分(ex this.name = "Bob";)。如果你想将它从其他类中隐藏(以尊重封装)并使其成为私有的,你将无法在子类中使用它(除了公共的get和set函数)。要隐藏它但在子类中使用它,您需要保护它。这允许子类查看它,同时将其隐藏到其他类。然后,您就可以像公开时那样使用它。

问题2:

Student stud1 = new UnderGraduate("Senior", "mom", "New York");

这声明了一个Student类型的变量,并在其中放置了UnderGraduate类型的对象。这样做的好处是允许您在此变量中放置Student的任何子类(如果它有多个)的对象(这称为"多态性")。缺点是,如果要使用特定于子类的字段或函数(不在超类中),则需要每次都在子类中转换此变量。

UnderGraduatestud1 = new UnderGraduate("Senior", "mom", "New York");

这声明了一个变量并且实例化了一个相同类型的对象(UnderGrade)。优点是允许您使用子类的任何特定函数和字段而不进行转换,唯一的缺点是不具备先前方法的优势。

Student stud1 = new Student("Senior", "mom", "New York");

这是行不通的,因为您尝试使用Student的构造函数来实现Student类的对象,但Undergrade类的签名(参数)。但是,Student不包含该构造函数签名的定义,因此您的代码无法编译。你必须使用两个第一个方法中的任何一个,因为这些是我所知道的唯一方法。

我希望已经回答了你所有的问题,如果我这样做的话,如果你愿意支持并将我的答案标记为正确,我会非常感激(我是新来的,而且我试图获得声誉)。< / p>

答案 1 :(得分:-1)

通常,继承是为了重用代码。例如,学生类可以由undergrad,postgrad等继承,但关键是派生类通用的任何内容都将转到父类。

但是,有一条规则(最佳实践)更喜欢使用Composition而不是继承(这会减少耦合

只要您在父级中拥有protected或public属性,就可以从派生类访问它。

拥有父类变量的优点是可以从不同派生类的不同实例分配该变量。