Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在从抽象类派生的类中创建新方法?_C#_Oop_Inheritance_Polymorphism_Abstract Class - Fatal编程技术网

C# 如何在从抽象类派生的类中创建新方法?

C# 如何在从抽象类派生的类中创建新方法?,c#,oop,inheritance,polymorphism,abstract-class,C#,Oop,Inheritance,Polymorphism,Abstract Class,在下面的示例中,我使用C# 我创建了一个抽象类Base\u Collection,然后从中派生出其他类(Book,Movie,Game)。但是,我不知道如何添加新方法,以便在不出现编译器错误的情况下用于这些新的子类 namespace polymorphism_test_01 { abstract class Base_Collection { public int id = 0; public string title = "";

在下面的示例中,我使用C#

我创建了一个抽象类
Base\u Collection
,然后从中派生出其他类(
Book
Movie
Game
)。但是,我不知道如何添加新方法,以便在不出现编译器错误的情况下用于这些新的子类

namespace polymorphism_test_01
{
    abstract class Base_Collection
    {
        public int id = 0;
        public string title = "";

        public Base_Collection() { }
    }
}    

namespace polymorphism_test_01
{
    class Book : Base_Collection
    {
        public Book() { }

        public override void Read_Book() { }
    }
}    

namespace polymorphism_test_01
{
    class Game : Base_Collection
    {
        public Game() { }

        public void Play_Game() { }
    }
}   

namespace polymorphism_test_01
{
    class Movie : Base_Collection
    {
        public Movie() { }

        public void Watch_Movie() { }
    }
}
在以下代码段中调用
book.Read\u book()
无效,编译器将输出错误:

namespace polymorphism_test_01
{
    class Program
    {
        public static void Main(string[] args)
        {
            Base_Collection book = new Book();

            book.title = "The Dark Tower";
            book.Read_Book();

            Console.WriteLine(book.title);
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}

Base\u Collection
没有名为
Read\u Book
的方法。要在派生类上调用该方法,需要强制转换,例如

(Book)book.Read_Book();

Base\u Collection
没有名为
Read\u Book
的方法。要在派生类上调用该方法,需要强制转换,例如

(Book)book.Read_Book();

无法覆盖不存在的方法。删除
覆盖
,然后在接受该方法之前强制转换,就像威尔提到的那样

class Book : Base_Collection
{
    public Book()
    {

    }

    public void Read_Book()
    {

    }
}


public static void Main(string[] args)
{
    Base_Collection book = new Book();

    book.title = "The Dark Tower";
    (Book)book.Read_Book();
    ...
}

然而,我只是创建一个Book对象,而不是强制转换它,否则您将不得不在程序中进行大量强制转换。甚至可以像slugster提到的那样重新考虑类的层次结构。

您不能覆盖一个不存在的方法。删除
覆盖
,然后在接受该方法之前强制转换,就像威尔提到的那样

class Book : Base_Collection
{
    public Book()
    {

    }

    public void Read_Book()
    {

    }
}


public static void Main(string[] args)
{
    Base_Collection book = new Book();

    book.title = "The Dark Tower";
    (Book)book.Read_Book();
    ...
}

然而,我只是创建一个Book对象,而不是强制转换它,否则您将不得不在程序中进行大量强制转换。甚至可以像slugster提到的那样重新考虑阶级层次结构。

进一步从@Will(这是正确的)得到答案,你可以更好地构建你的继承权。例如,您对每种媒体类型都做了不同的操作,但每种类型仍然会被使用

class Book : Base_Collection
{
    public Book()
    {

    }

    public void Read_Book()
    {

    }
}


public static void Main(string[] args)
{
    Base_Collection book = new Book();

    book.title = "The Dark Tower";
    (Book)book.Read_Book();
    ...
}
因此,将基类更改为具有名为
Consume()
的抽象基类方法,然后在每个派生类中重写并实际实现该方法,这样您就可以传递基类的实例,而无需强制转换来调用每种媒体类型上的
Consume()
方法:

public abstract class Base_Collection
{

    public int id = 0;
    public string title = "";

    public Base_Collection() {   }

    public abstract void Consume();

}

public class Book : Base_Collection
{
    public Book() {   }

    public override void Consume()
    {
        //do book reading stuff in here
    }
}

public class Movie : Base_Collection
{
    public Movie() {   }

    public override void Consume()
    {
        //do movie watching stuff in here
    }
}



public class SomeOtherClass
{
    public void SomeMethod(Base_Collection mediaItem)
    {
        //note that the book/movie/whatever was passed as the base type
        mediaItem.Consume();
    }
}

根据@Will的回答(这是正确的),您可以更好地构建您的继承权。例如,您对每种媒体类型都做了不同的操作,但每种类型仍然会被使用

因此,将基类更改为具有名为
Consume()
的抽象基类方法,然后在每个派生类中重写并实际实现该方法,这样您就可以传递基类的实例,而无需强制转换来调用每种媒体类型上的
Consume()
方法:

public abstract class Base_Collection
{

    public int id = 0;
    public string title = "";

    public Base_Collection() {   }

    public abstract void Consume();

}

public class Book : Base_Collection
{
    public Book() {   }

    public override void Consume()
    {
        //do book reading stuff in here
    }
}

public class Movie : Base_Collection
{
    public Movie() {   }

    public override void Consume()
    {
        //do movie watching stuff in here
    }
}



public class SomeOtherClass
{
    public void SomeMethod(Base_Collection mediaItem)
    {
        //note that the book/movie/whatever was passed as the base type
        mediaItem.Consume();
    }
}

您可以向基类添加方法,而不会出现任何问题。出现编译器错误的原因是您错误地使用了
override
关键字

为了使用
override
关键字,方法名称和签名必须与父类中的方法名称和签名相匹配,并且方法必须在基类中标记为
virtual
abstract
。这两者之间的区别得到了回答

既然书、电影和电影都可以“表演”,你可能想考虑这样做:
abstract class Base_Collection
{
    public int id = 0;
    public string title = "";

    public Base_Collection() { }

    public virtual void PerformAction() { } // or public virtual void PerformAction(){ }
}

class Book : Base_Collection
{
    public Book() { }

    public override void PerformAction() { // read book }
}

class Game : Base_Collection
{
    public Game() { }

    public override void PerformAction() { // play game }
}

class Movie : Base_Collection
{
    public Movie() { }

    public void PerformAction() { // watch movie }
}

您可以向基类添加方法,而不会出现任何问题。出现编译器错误的原因是您错误地使用了
override
关键字

为了使用
override
关键字,方法名称和签名必须与父类中的方法名称和签名相匹配,并且方法必须在基类中标记为
virtual
abstract
。这两者之间的区别得到了回答

既然书、电影和电影都可以“表演”,你可能想考虑这样做:
abstract class Base_Collection
{
    public int id = 0;
    public string title = "";

    public Base_Collection() { }

    public virtual void PerformAction() { } // or public virtual void PerformAction(){ }
}

class Book : Base_Collection
{
    public Book() { }

    public override void PerformAction() { // read book }
}

class Game : Base_Collection
{
    public Game() { }

    public override void PerformAction() { // play game }
}

class Movie : Base_Collection
{
    public Movie() { }

    public void PerformAction() { // watch movie }
}

您应该从public override void Read_Book()中删除override关键字,或者像下面这样将此函数添加到Base_集合中

    public abstract void Read_Book();

您应该从public override void Read_Book()中删除override关键字,或者像下面这样将此函数添加到Base_集合中

    public abstract void Read_Book();

这并不能解决一个事实,即该方法不存在,因此无法在一开始就重写。这也不能解决一个事实,即该方法不存在,因此无法在一开始就重写。嘿,我正在使用你的示例,但编译器仍然不想接受它。编辑:太糟糕了,我不能在注释时显示代码。使用系统;命名空间多态性\u test\u 01{public abstract class Base\u Collection{public int id=0;public string title=“”;public Base\u Collection(){}}public class Book:Base\u Collection{public Book(){}public void Read\u Book(){}class程序{public static void Main(string[]args){Base_Collection book=new book();book.title=“The Dark Tower”;(book)book.Read_book();}}}}错误是:“Error CS0201:只能将赋值、调用、递增、递减和新对象表达式用作语句”和“'polymorphism_test_01.Base_Collection'不包含'Read_Book'的定义,并且找不到接受'polymorphism_test_01.Base_Collection'类型的第一个参数的扩展方法'Read_Book'(是否缺少using指令或程序集引用?)“好的,在您的示例中,您在Base_集合中添加了Read_Book方法,但实际上我不希望这样做。假设我真的需要添加一个只针对图书派生类而非其他类的方法?@TheScholar实际上没有,我只是删除了
override
关键字。ReadBook仅对Book类可用。但是,您应该真正实现其他答案提到的东西,至少可以避免强制转换。编辑:太糟糕了,我不能在注释时显示代码。使用系统;命名空间多态性测试01{公共抽象类基类集合