C# 如何在从抽象类派生的类中创建新方法?
在下面的示例中,我使用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 = "";
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{公共抽象类基类集合