我收到错误:"类型Book'不包含0'的构造函数参数"当我尝试按如下方式设置构造函数时:
using System;
using System.Collections.Generic;
using System.IO;
abstract class Book
{
protected String title;
protected String author;
public Book(String t,String a){
title=t;
author=a;
}
public abstract void display();
}
class MyBook : Book
{
private int price = 0;
public MyBook(string t, string a, int p)
{
base.title = t;
base.author = a;
this.price = p;
}
public override void display()
{
Console.WriteLine($"Title: {title}");
Console.WriteLine($"Author: {author}");
Console.WriteLine($"Price: {price}");
}
}
我已将问题缩小到如何使用base关键字。我应该在其构造函数声明中使用base构造函数初始化器和base关键字。
public MyBook(string t, string a, int p)
: base(t, a)
{
this.price = p;
}
有人请向我解释为什么我不能使用base。在我的构造函数中?是因为标题和作者变量都是抽象类的受保护成员吗?我认为,因为我是从Book中获得的,所以我可以访问这些受保护的成员。或者是因为我没有实例化我的子类,因此我无法以这种方式设置我的构造函数?
答案 0 :(得分:1)
如果你编写一个没有构造函数的类,编译器会为你定义一个无参数的默认构造函数,以方便编写简单的quickie类。
当您开始显式定义构造函数时,编译器会假定您正在定义您想要的构造函数集。这使您可以控制如何创建类,同时保留编写使用默认构造函数的简单类的便利性。
MyBook
是Book
。在MyBook
初始化之前,Book
必须首先执行此操作。但是这里没有无参数构造函数。就编译器而言,Book
已明确选择禁止您在此处执行的操作。该语言假设如果你想让人 - 子类,你的姨妈莎莉,任何人 - 能够用无参数构造函数创建Book
,你就提供了一个。
public MyBook(string t, string a, int p)
{
base.title = t;
base.author = a;
this.price = p;
}
答案 1 :(得分:1)
您可以按照您尝试的方式使用受保护的属性。这不是你遇到的问题。当您尝试创建派生类的实例时,程序需要知道要调用的基类的哪个构造函数来创建该对象的该部分。如果您没有指定,则调用默认(无参数)构造函数。基类没有其中一个,所以你得到错误。 :base(t,a)
必须告诉它使用WHICH构造函数,以及传递它的参数。如果你愿意,你可以这样做:
public MyBook(string t, string a, int p)
: base(t, a)
{
base.title = t;
base.author = a;
this.price = p;
}
当然,在这个愚蠢的例子中,你可以看到它会让你以你尝试的方式使用这些属性。
答案 2 :(得分:0)
您无法在不调用构造函数的情况下设置基类的属性。因为基类有一个带参数的构造函数(并且没有默认构造函数),所以必须显式调用基类的构造函数。
public MyBook(string t, string a, int p)
:base(t, a)
{
this.price = p;
}
创建派生类的实例时,实际上是在创建基类的实例。如果一个类具有需要参数的构造函数并且不会具有默认构造函数,那么创建它的唯一方法是调用其中一个构造函数。
如果Book
和MyBook
在同一个程序集中,那么您可以添加一个只有继承类可以调用的protected
默认构造函数,如下所示:
protected Book() { }
但要做到这一点,不会更好。你把那个构造函数放在那里是有原因的,所以你不需要任何东西"绕过"那个构造函数 - 甚至不是一个继承的类。
例如,您可能认为Book
无法使用title
或author
,因此您需要在构造函数中进行验证,以确保它们不是&#39 ; t null。 MyBook
调用基类构造函数是件好事,因为现在验证总是发生。
答案 3 :(得分:0)
虽然有多种方法可以解决您的问题。我将尝试以更好的设计视角回答,而不仅仅是解决您的问题。
如果我要定义这样的类结构,我会像这样做
using System;
using System.Collections.Generic;
using System.IO;
abstract class Book
{
protected String title;
protected String author;
public Book(String t, String a)
{
this.title = t;
this.author = a;
}
public abstract void display();
}
class MyBook : Book
{
private int price = 0;
public MyBook(string t, string a, int p) : base(t, a) // Let the base class decide what it wants to do with these arguments
{
this.price = p;
}
public override void display()
{
Console.WriteLine($"Title: {title}");
Console.WriteLine($"Author: {author}");
Console.WriteLine($"Price: {price}");
}
}