简体   繁体   English

为什么这样做? 遗产

[英]Why does this work? Inheritance

No problems here, just need explanation how does that work. 这里没有问题,只需要解释它是如何工作的即可。

I was doing homework for my C# class and I managed to do it by myself by following code examples provided by our professor. 我当时在为C#类做功课,我设法通过遵循教授提供的代码示例来自己完成作业。 The problem is I don't get how it works. 问题是我不知道它是如何工作的。 Here are things that boggle me: 这是令我惊讶的事情:

First of all, how come I need to use xmlBook.Title = "XML Primer Plus"; 首先,为什么需要使用xmlBook.Title = "XML Primer Plus"; instead of Book clrBook = new Book("CLR via C#", ...") and vice-versa as constructors. 而不是Book clrBook = new Book("CLR via C#", ...") ,反之亦然。

Second, why I don't have to have any parameters when using : base() ? 其次,为什么在使用: base()时不必具有任何参数?

Third, how does overwrite by using new public void display() only adds output, instead of completely modifying original protected void display() ? 第三,如何使用new public void display()覆盖仅添加输出,而不是完全修改原始protected void display() I guess because the original diplay() is protected? 我猜是因为原始的diplay()受保护了吗?

Please clarify 请澄清

Regards. 问候。

Main.cs Main.cs

using System;

namespace Lab_4
{
    class Program
    {
        static void Main(string[] args)
        {
            Book xmlBook = new Book();
            xmlBook.Title = "XML Primer Plus";
            xmlBook.AuthorFirstName = "Nicolas";
            xmlBook.AuthorLastName = "Chase";
            xmlBook.Price = 44.99F;
            xmlBook.PublisherName = "Sams Publishing";

            Book clrBook = new Book("CLR via C#", 
                                    "Jeffrey", 
                                    "Richter", 
                                    59.99f, 
                                    "Microsoft Press");

            Console.WriteLine("=== xmlBook ===");
            xmlBook.display();
            Console.WriteLine();
            Console.WriteLine("=== clrBook ===");
            clrBook.display();
        }
    }
}

Publication.cs Publication.cs

using System;

namespace Lab_4
{
    public class Publication
    {
        string publisherName, title;
        float price;

        public Publication()
        {
        }

        public Publication(string title, 
                           string publisherName, 
                           float price)
        {
            Title = title;
            PublisherName = publisherName;
            Price = price;
        }

        public float Price
        {
            set
            {
                price = value;
            }
        }

        public string PublisherName
        {
            set
            {
                publisherName = value;
            }
        }

        public string Title
        {
            set
            {
                title = value;
            }
        }

        protected void display()
        {
            Console.Write("{0}\n{1}\n{2}\n", title, publisherName, price);
        }
    }
}

Book.cs Book.cs

using System;

namespace Lab_4
{
   public class Book : Publication
    {
        string authorFirstName, authorLastName;

        public Book()
        {
        }

        public Book(string bookTitle, 
                    string firstName, 
                    string lastName, 
                    float bookPrice, 
                    string publisherName)
           : base()
        {
            Title = bookTitle;
            AuthorFirstName = firstName;
            AuthorLastName = lastName;
            Price = bookPrice;
            PublisherName = publisherName;
        }

        public string AuthorFirstName
        {
            get
            {
                return authorFirstName;
            }
            set
            {
                authorFirstName = value;
            }
        }

        public string AuthorLastName
        {
            get
            {
                return authorLastName;
            }
            set
            {
                authorLastName = value;
            }
        }

        new public void display()
        {
            base.display();
        Console.WriteLine("{0}", getAuthorName());
        }

        string getAuthorName()
        {
            return AuthorFirstName + " " + AuthorLastName;
        }
    }
}

First of all, how come I need to use xmlBook.Title = "XML Primer Plus"; 首先,为什么需要使用xmlBook.Title =“ XML Primer Plus”; instead of Book clrBook = new Book("CLR via C#", ...") and vice-versa as constructors. 而不是Book clrBook = new Book(“ CLR via C#”,...“),反之亦然。

You are free to swap them if you like. 如果愿意,您可以自由交换它们。 Either option works, which is what that code is trying to demonstrate. 任一个选项都有效,这就是该代码试图演示的内容。

There are multiple constructors for the Book class. Book类有多个构造函数。 From code outside the class (like in your Main method), you are allowed to call any constructor of the class that is marked public . 从类外部的代码(例如在Main方法中),您可以调用标记为public的类的任何构造函数。

The reason you need to set the properties when you call new Book(); 调用new Book();时需要设置属性的原因new Book(); is because that constructor doesn't set the properties of the class. 这是因为该构造函数未设置类的属性。 When you call new Book("CLR via C#", "Jeffrey", "Richter", etc); 当您调用new Book("CLR via C#", "Jeffrey", "Richter", etc); , you are calling the constructor that does set the properties. ,您正在调用确实设置属性的构造函数。

Second, why I don't have to have any parameters when using : base()? 第二,为什么在使用:base()时我不必具有任何参数?

The base class ( Publication ) also has two constructors. 基类( Publication )也有两个构造函数。 When calling base() , you are calling the constructor of Publication that takes no parameters. 调用base() ,正在调用不带参数的Publication的构造函数。

When you call the constructor for a derived class, some constructor for the base class will always get called. 当您为派生类调用构造函数时,总是会调用基类的某些构造函数。 If you don't explicitly specify which of the base class's constructors you want to call (by calling base() or base("some title", "some publisher name", 0.0f /* some price */) ), then the parameterless constructor (ie public Publication() ) will be called by default. 如果您没有明确指定要调用的基类构造函数(通过调用base()base("some title", "some publisher name", 0.0f /* some price */) ),则默认情况下,将调用无参数构造函数(即public Publication() )。

Third, how does overwrite by using new public void display() only adds output, instead of completely modifying original protected void display()? 第三,如何使用新的公共void display()覆盖仅添加输出,而不是完全修改原始受保护的void display()? I guess because the original diplay() is protected? 我猜是因为原始的diplay()受保护了吗?

It doesn't have anything to do with it being protected. 它与被保护没有任何关系。 Try changing it to public , and you'll see the same behavior. 尝试将其更改为public ,您将看到相同的行为。

The way it "adds" behavior is by actually calling that function in the base class. 它“添加”行为的方式是通过在基类中实际调用该函数。 The line base.display(); base.display(); calls that function. 调用该函数。 If that line weren't there, the base class's function would effectively be "replaced". 如果该行不存在,则将有效地“替换”基类的功能。

There is only one thing that protected means. protected手段只有一件事。 It means you can't call it from outside code - you can only call it from within the same class (from within Publication ) and from inside a derived class ( Book ). 这意味着您不能从外部代码中调用它-您只能从同一类(在Publication内)和派生类( Book )内调用它。 protected will not "protect" it from being overridden in derived classes (either using override or new ). protected不会“保护”它以免在派生类中被覆盖(使用overridenew )。

1.) It's using the constructor of Book that takes no parameters hence 1.)使用Book的构造函数,因此不带任何参数

Book xmlBook = new Book();

The rest is just assigning public properties. 剩下的只是分配公共财产。

2.) base() is calling the constructor of the base class - since the Publication constructor does not have any parameters, you don't have to (and can't) pass any. 2.) base()正在调用基类的构造函数-由于Publication构造函数没有任何参数,因此您不必(也不能)传递任何参数。 Note that in this case calling base() is optional because the base class provides an empty constructor. 请注意,在这种情况下,调用base()是可选的,因为基类提供了一个空的构造函数。 Also see "Using Constructors " as reference. 另请参见“使用构造函数 ”作为参考。

3.) The display() method in Book is calling the display() method of the base class as part of its implementation, that's why there is additional output. 3.) display()在方法Book是调用display()基类的方法,其实现的一部分,这就是为什么有附加的输出。 Note that because the method signature is using new public void the method in the Book class is only called if you use via Book reference, usually you want to use override instead. 请注意,由于方法签名使用的是new public void ,因此仅在通过Book引用使用时,才调用Book类中的方法,通常,您想使用override

1) With xmlBook , you call the constructor without params, public Book() , and then set the individual fields. 1)使用xmlBook ,您可以调用不带参数的构造函数public Book() ,然后设置各个字段。

2) In the constructor for Books with params, you could call base with some of the params, namely title , publisherName and price . 2)在带参数的Books的构造函数中,您可以使用一些参数来调用base ,即titlepublisherNameprice An alternative (which is what you have), is to set all the fields in the Books constructor itself. 一种替代方法(就是您所拥有的)是在Books构造函数本身中设置所有字段。

3) Books.display() adds output to Publication.display() , instead of replacing it, because it calls base.display() . 3) Books.display()将输出添加到Publication.display() ,而不是替换输出,因为它调用base.display()

First Question 第一个问题

Publication has public Title property. 出版物具有公共标题属性。 Book is a Publication and so you can call 图书是出版物,因此您可以致电

Book xmlBook = new Book();
xmlBook.Title = "XML Primer Plus";

Second Question 第二个问题

Publication has a constructor that doesn't have any parameters. 发布的构造函数没有任何参数。 So you can call it as base() from the Book class. 因此,您可以从Book类中将其作为base()调用。

   public Publication()
    {
    }

Third Question 第三题

Display method in the Book class calls the Display method in the Publication class. Book类中的Display方法调用Publication类中的Display方法。 Note that if you use the new modifier instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. 请注意,如果使用new修饰符而不是override,则派生类中的方法不会覆盖基类中的方法,而只是将其隐藏。 Look at this thread for more information. 查看此线程以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM