通过基类来声明派生类有何意义?

sqn1982 2015-12-09 02:28:53
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class Program
{
static void Main()
{
MyBaseClass c = new MyDerivedClass();

Console.ReadLine();
}
}

public class MyBaseClass
{
public void MethodOne()
{
}
}

public class MyDerivedClass : MyBaseClass
{
public void MethodTwo()
{
}
}
}


如上面的代码MyBaseClass是一个基类,MyDerivedClass是派生于MyBaseClass的一个类,
通过MyBaseClass声明一个MyDerivedClass的一个派生类c?
程序是允许这样做的,但这样做的意义何在?
为什么不能直接用MyDerivedClass派生类来声明呢?
...全文
215 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
变成教程 --> 编程教程 很显然地,书上的这个例子设计得很不好,过于简单了。如果如邯郸学步一样去学了这个例子,就可能胡乱抽象。但是这可能也说明了,你看的这本书的面对的读者的素质不高。
  • 打赏
  • 举报
回复
初学者就好像是等待在围栏中等待喂食的家猪,它不去想围栏之外的野猪去想的事情。当一个变成教程告诉人一点点“设计的”知识时,理解起来就可能显得“困难”,而且写起来也困难。 就像这个例子一样,它没有真正告诉你为什么要多态,只能用一个枯燥的“程序是允许这样做的”的简单的一行代码的例子让你模仿。这时候就容易产生过分的想象空间。
  • 打赏
  • 举报
回复
引用 楼主 sqn1982 的回复:
如上面的代码MyBaseClass是一个基类,MyDerivedClass是派生于MyBaseClass的一个类, 通过MyBaseClass声明一个MyDerivedClass的一个派生类c? 程序是允许这样做的,但这样做的意义何在? 为什么不能直接用MyDerivedClass派生类来声明呢?
就编程而言,在 Main 方法中直接写
MyDerivedClass c = new MyDerivedClass();
显然更具体一些。因为一个MyDerivedClass对象它本身“就是”一个MyBaseClass对象,只要知道这个道理用在设计中,那么没有必要在代码上搞这个。 假设写代码的人想说变量c的类型其实是不确定的(也就是说,根本不确定MyDerivedClass实例,可能随后就要改为另外一种MyBaseClass子类实例),那么才应该暂时这样写。 而教程中给你这样写,最大的可能就像你说的“程序是允许这样做”而已,因此是一个给初学者教学的示范。 真正懂的抽象的人,反而不会胡乱抽象代码。如果可以使用具体类型,那么就尽量使用具体类型。我们在开发中自然是声明的类型(和接口)越少越好,代码写得越少越好。代码可以重构,而不是一开始就搞抽象的东西。
Poopaye 2015-12-09
  • 打赏
  • 举报
回复
引用 8 楼 sqn1982 的回复:
你这个语法都错了,根本就没有实现继承!也就无从谈override 了!
直接打的,漏掉了: BaseClass
crystal_lz 2015-12-09
  • 打赏
  • 举报
回复
引用 8 楼 sqn1982 的回复:
[quote=引用 5 楼 shingoscar 的回复:] 这样写就能显得有意义了
abstract class BaseClass
{
      public abstract void Method();
}

class DerivedClass1
{
      public override void Method() { Console.WriteLine("This is DerivedClass1"); }
}

class DerivedClass2
{
      public override void Method() { Console.WriteLine("This is DerivedClass2"); }
}

class Worker
{
      public static void Add(BaseClass obj) { obj.Method(); }
}
使用时:
BaseClass obj1 = new DerivedClass1();
Worker.Add(obj1);
BaseClass obj2 = new DerivedClass2();
Worker.Add(obj2);
你这个语法都错了,根本就没有实现继承!也就无从谈override 了![/quote] too yang...
sqn1982 2015-12-09
  • 打赏
  • 举报
回复
引用 5 楼 shingoscar 的回复:
这样写就能显得有意义了
abstract class BaseClass
{
      public abstract void Method();
}

class DerivedClass1
{
      public override void Method() { Console.WriteLine("This is DerivedClass1"); }
}

class DerivedClass2
{
      public override void Method() { Console.WriteLine("This is DerivedClass2"); }
}

class Worker
{
      public static void Add(BaseClass obj) { obj.Method(); }
}
使用时:
BaseClass obj1 = new DerivedClass1();
Worker.Add(obj1);
BaseClass obj2 = new DerivedClass2();
Worker.Add(obj2);
你这个语法都错了,根本就没有实现继承!也就无从谈override 了!
衣舞晨风 2015-12-09
  • 打赏
  • 举报
回复
crystal_lz 2015-12-09
  • 打赏
  • 举报
回复
C# 自带的一些函数 里面 很多参数都是使用的基类啊 首先 基类有的属性和方法 子类是肯定有的 也就是说 子类毫无疑问的可以被当作基类来用 所以说 在一些函数中 比如 Graphics.DrawImage(Image ...) 中 使用的是 Image(基类) 作为参数 而不是子类 这样DrawImage函数 就能适应各种Image或者继承值Image的类了 因为DrawImage要的只是图像数据是一个Image对象都有的数据 所以说 那些继承至Image的类所多出来的那些细微区别 对于DrawImage而言 毫无意义 因为他要的只是图像数据然后绘制出来 如果说 DrawImage 的参数写死比如 他接受一个 Bitmap 类型 那么这个函数所能接受的参数范围 就大大降低了 虽然说可以直接强制转换DrawImage((Bitmap)img)这样之类的。。看着也会别扭吧。。。 也就是说 如果你关心的只是所有类的公共部分 而不是那些什么细微的区别 就用基类 因为他可以通用所有子类。。。
Poopaye 2015-12-09
  • 打赏
  • 举报
回复
这样写就能显得有意义了
abstract class BaseClass
{
      public abstract void Method();
}

class DerivedClass1
{
      public override void Method() { Console.WriteLine("This is DerivedClass1"); }
}

class DerivedClass2
{
      public override void Method() { Console.WriteLine("This is DerivedClass2"); }
}

class Worker
{
      public static void Add(BaseClass obj) { obj.Method(); }
}
使用时:
BaseClass obj1 = new DerivedClass1();
Worker.Add(obj1);
BaseClass obj2 = new DerivedClass2();
Worker.Add(obj2);
好几只小萝莉 2015-12-09
  • 打赏
  • 举报
回复
引用 3 楼 sqn1982 的回复:
[quote=引用 1 楼 bdmh 的回复:] 这就是多态的用法,虽然什么的是基类,但是由具体的子类去实现,所以如果有另一个模块,需要这样一个对象时,只需声明为基类,而不用关系到底是哪个子类
如果这种方法引用的话派生类中的方法不就使用不到了吗? 比如上面的例子,c只能引用MethodOne(),而不能引用MethodTwo()?[/quote] 一定要用的话,可以这么做 MyBaseClass c = new MyDerivedClass(); MyDerivedClass cc = c as MyDerivedClass; cc.MethodTwo(); ======================================== 既然是基类声明,那么就只能用基类声明了的方法。 动物 a = new 鸟(); a.吃();//你可以这么写,因为我们知道a是动物,动物都能吃。 a.飞();//你不能这么写,因为我们知道a是动物,然而并不是所有动物都能飞。 其实我认为更重要的是理解上的一种解决:我既然new的是一个人,那么我让这个对象做能做的事,而不能让这个对象去做男人才能做的事。
sqn1982 2015-12-09
  • 打赏
  • 举报
回复
引用 1 楼 bdmh 的回复:
这就是多态的用法,虽然什么的是基类,但是由具体的子类去实现,所以如果有另一个模块,需要这样一个对象时,只需声明为基类,而不用关系到底是哪个子类
如果这种方法引用的话派生类中的方法不就使用不到了吗? 比如上面的例子,c只能引用MethodOne(),而不能引用MethodTwo()?
  • 打赏
  • 举报
回复
开放封闭原则
bdmh 2015-12-09
  • 打赏
  • 举报
回复
这就是多态的用法,虽然什么的是基类,但是由具体的子类去实现,所以如果有另一个模块,需要这样一个对象时,只需声明为基类,而不用关系到底是哪个子类

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧