Почему это работает? наследование - PullRequest
1 голос
/ 20 сентября 2011

Здесь нет проблем, просто нужно объяснить, как это работает.

Я делал домашнюю работу для своего класса C #, и мне удалось сделать это самостоятельно, следуя примерам кода, предоставленным нашим профессором. Проблема в том, что я не понимаю, как это работает. Вот вещи, которые меня поражают:

Прежде всего, почему мне нужно использовать xmlBook.Title = "XML Primer Plus"; вместо Book clrBook = new Book("CLR via C#", ...") и наоборот в качестве конструкторов.

Во-вторых, почему я не должен иметь никаких параметров при использовании : base()?

В-третьих, как перезапись с помощью new public void display() только добавляет вывод, а не полностью изменяет исходный protected void display()? Я думаю, потому что оригинал diplay() защищен?

Пожалуйста, уточните

Привет.

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

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

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;
        }
    }
}

Ответы [ 4 ]

2 голосов
/ 20 сентября 2011

Прежде всего, почему мне нужно использовать xmlBook.Title = "XML Primer Plus"; вместо Book clrBook = new Book ("CLR via C #", ... ") и наоборот как конструкторы.

Вы можете поменять их, если хотите. Любой из вариантов работает, что и пытается продемонстрировать этот код.

Существует несколько конструкторов для класса Book. Из кода вне класса (как в вашем Main методе) вы можете вызывать любой конструктор класса, помеченный public.

Причина, по которой вам нужно установить свойства при вызове new Book();, заключается в том, что этот конструктор не устанавливает свойства класса. Когда вы вызываете new Book("CLR via C#", "Jeffrey", "Richter", etc);, вы вызываете конструктор, который устанавливает для установки свойств.

Во-вторых, почему у меня не должно быть никаких параметров при использовании: base ()?

Базовый класс (Publication) также имеет два конструктора. При вызове base() вы вызываете конструктор Publication, который не принимает параметров.

Когда вы вызываете конструктор для производного класса, всегда вызывается какой-то конструктор для базового класса. Если вы не укажете явно, какой из конструкторов базового класса вы хотите вызвать (вызывая base() или base("some title", "some publisher name", 0.0f /* some price */)), то по умолчанию будет вызван конструктор без параметров (т.е. public Publication()).

В-третьих, как перезапись с использованием нового открытого void display () только добавляет вывод вместо полной модификации исходного защищенного void display ()? Я думаю, потому что оригинальный diplay () защищен?

Это не имеет ничего общего с тем, что оно защищено. Попробуйте изменить его на public, и вы увидите то же поведение.

Способ, которым он «добавляет» поведение, заключается в том, чтобы фактически вызывать эту функцию в базовом классе. Строка base.display(); вызывает эту функцию. Если бы этой строки не было, функция базового класса была бы фактически «заменена».

Есть только одна вещь, которая означает protected. Это означает, что вы не можете вызывать его из внешнего кода - вы можете вызывать его только из одного и того же класса (изнутри Publication) и из производного класса (Book). protected не будет "защищать" его от переопределения в производных классах (с использованием override или new).

1 голос
/ 20 сентября 2011

1) С помощью xmlBook вы вызываете конструктор без параметров, public Book(), а затем устанавливаете отдельные поля.

2) В конструкторе для Books с параметрами вы можете вызвать base с некоторыми из параметров, а именно title, publisherName и price.Альтернатива (это то, что у вас есть) состоит в том, чтобы установить все поля в самом конструкторе Books.

3) Books.display() добавляет вывод к Publication.display() вместо его замены, потому что он вызывает base.display().

1 голос
/ 20 сентября 2011

Первый вопрос

Публикация имеет публичное свойство Title. Книга является Публикацией, и поэтому вы можете позвонить

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

Второй вопрос

Публикация имеет конструктор, который не имеет никаких параметров. Так что вы можете вызвать его как base () из класса Book.

   public Publication()
    {
    }

Третий вопрос

Метод Display в классе Book вызывает метод Display в классе Publication. Обратите внимание: если вместо переопределения вы используете новый модификатор , метод в производном классе не переопределяет метод в базовом классе, он просто скрывает его. Посмотрите на эту тему для получения дополнительной информации.

1 голос
/ 20 сентября 2011

1.) Он использует конструктор Book, который не принимает параметров, следовательно,

Book xmlBook = new Book();

Остальное просто присваивание общедоступных свойств.

2.) base() вызывает конструктор базового класса - поскольку конструктор Publication не имеет никаких параметров, вы не должны (и не можете) передавать их. Обратите внимание, что в этом случае вызов base() является необязательным, поскольку базовый класс предоставляет пустой конструктор. Также см. «Использование конструкторов » для справки.

3.) Метод display() в Book вызывает метод display() базового класса как часть его реализации, поэтому есть дополнительный выход. Обратите внимание, что поскольку сигнатура метода использует new public void, метод в классе Book вызывается только в том случае, если вы используете ссылку Book, обычно вместо этого вы хотите использовать override.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...