《1》两个虚假的东西 virtual 与 abstract(一般选用 virtual ,没有用上abstract)《2》两个重写的区别 override 与 new (我应该用那一个,我只会从中随便选一个来用,一般选 override )不知大家 能不能举例说说 自已是如何用 这两组东东的?
《1》两个虚假的东西 virtual 与 abstract(一般选用 virtual ,没有用上abstract)《2》两个重写的区别 override 与 new (我应该用那一个,我只会从中随便选一个来用,一般选 override )不知大家 能不能举例说说 自已是如何用 这两组东东的?
abstract修饰专门被继承的基类,比如ReadOnlyCollectionBase
abstract方法貌似都直接扔去接口里了
new 运算符 1.用于创建对象和调用构造函数 例:Class_Test MyClass = new Class_Test(); 2.也用于为值类型调用默认的构造函数 例:int myInt = new int(); myInt 初始化为 0,它是 int 类型的默认值。该语句的效果等同于:int myInt = 0; 3.不能重载 new 运算符。 4.如果 new 运算符分配内存失败,则它将引发 OutOfMemoryException 异常。 new 修饰符 使用 new 修饰符显式隐藏从基类继承的成员。若要隐藏继承的成员,请使用相同名称在派生类中声明该成员,并用 new 修饰符修饰它。
http://msdn.microsoft.com/zh-cn/library/9fkccyh4.aspx
http://msdn.microsoft.com/zh-cn/library/ebca9ah3.aspx
virtual 在实际项目按需求多用于实现多态
abstract 用于做基类override 是对继承的class or 抽象类实现对virtual abstract方法的重写 实现其逻辑
,对实现的interface的方法重写并实现其逻辑
new 二个用法:
Class objectName=new Instance();创建类的实例并将对对象的引用交给"="左边的变量、名称
用于覆盖父类的"同名同参"的非private修饰的方法
显然不对,怎么还这么多支持的?
override同样也可以重写virtual方法
虚方法可以有自己的实现,而抽象方法不能有方法体,也就不能有自己的实现。这两个关键字都用在可继承的类里(sealed类自然就不行了),子类在继承的时候,必须实现父类中的抽象方法,而虚方法则不是必须实现的。另外,包含抽象方法的类必须是抽象类,而包含虚方法的类可以是抽象类,也可以是非抽象类。
设计的时候如何选择呢?主要还是看你的这个类的这个方法是否可以包含默认实现,或者,它只是一个契约,没法提供任何实现。比如,人这个类,包含一个撒尿方法,你没法提供默认实现,因为不知道人怎么撒尿,所以只能设计为抽象方法,而对于男人和女人这两个继承自人的类,则完全可以提供站着撒尿和蹲着撒尿的实现,所以可以设计为虚方法,而男人的派生类“腿脚有毛病的男人”,没法站着撒尿,这时父类提供的默认实现就不合适了,所以必须改写。(2)override和new
override用于覆盖父类中同名的抽象方法和虚方法,所以上面那个腿脚有毛病的男人在改写父类中的撒尿方法时,就应该使用override。
new用于重写父类中的方法,可以是抽象方法、虚方法或普通方法。
override用于扩展和修改,new则是彻底地隐藏父类的方法。此外,这四个关键字都不止可以修饰方法,对于类中的其他成员,如属性、索引器、事件等也同样适用。
《2》两个重写的区别 override 与 new (我应该用那一个,我只会从中随便选一个来用,一般选 override )
override 子类覆盖父类中同名方法,new 子类的方法是子类的,基类的方法用基类的,各是各的,互不影响;
abstract:你必须自己搞一套。override:要找就来找我
new:我要把你们都遮了
意思是: 就这个区别,除处方面是通用的。
virtual
:这个关键字的方法, 本类可以写具体的现实,也可以不写。 他的子类也是 一样(具体现实代码可以写也可以不写)
abstract
:这个方法 必须出现在 abstract(抽象)类中,这个方法的现实代码不能写,他的子类,如果不是 abstract(抽象)类,那就一定要写具体的现实代码。
override
:就这方法改写, 他的子类的同名方法,一定是以下几种(abstract,virtual,override)的,这个方法的重写要事先声明。 否则编译出错
new
:这个方法的重写不要事先声明(不管有没有abstract,virtual,override 来修饰),不管什么方法都可以用这个来重写,与其重写,不如说他是 (另起炉灶),因为,他是另一个方法,他的子类方法还存在(没有覆盖),可以用base.[方法名](); 来调用。
用这个 关键字 的方法, 本类可以写具体现实的代码,也可以不写。
他的子类也是一样(具体现实代码可以写也可以不写)
abstract:[关键字] //抽象的,不能写内部代码,只表示有这个东东,却不说这个东东有什么特性
这个方法 必须出现在 abstract(抽象)类中,
这个方法的现实代码不能写,
在他的子类中,如果子类不是 abstract(抽象)类,那就一定要写具体的现实代码。
override:[关键字]//叫重写,也叫覆盖.基类要有标志
叫做重写,也叫改写,
他的子类的同名方法,一定是以下几种(abstract,virtual,override)的,
本类中这个方法必须要用(abstract,virtual,override)事先声明。 否则编译出错.
new:[关键字] //另起炉灶,是一个独立的,只是方法名与基类方法同名。
这个方法的重写不要事先声明(不管他的基类同名方法有没有abstract,virtual,override 来修饰),
不管什么方法都可以用这个来重写,与其说他是重写,不如说他是 (另起炉灶),
因为,他是另一个方法,他的子类方法还存在(没有覆盖),
可以用base.[方法名](); 来调用基类的方法。以上的(4个)说法有没有错误?(通过以上各位解答后的理解和个人总结。)
abstract :用在类上面 表示该类是抽象类 抽象类的方法就可以用virtual 也可以写具体实现
override :就是重写 表示重写virtual的方法
new :就是覆盖重写
想不出来什么情况下会需要这种效果
只知道:override 重写 要求他的基类的方法 要用(abstract,virtual,override) 修饰过的。
用 new 对他的 基类 的方法没有什么要求,编译都没有问题。对于 编译器内部生成的代码有什么不同,这个,真的不知。
{
static void Main(string[] args)
{
intList n = new intList();
n.Add(1);
n.Add(2);
n.Add(3);
foreach (int key in n)
{
Console.Write(key.ToString());
}
int count = n.RemoveAll();
Console.Write("有这么多个被clear了:"+count .ToString());
n.Add(4);
foreach (int key in n)
{
Console.Write(key.ToString());
}
Console.ReadKey();
}
}
public class intList:List<int>
{
public new int RemoveAll() //为什么在这里重写 ,这个new 可要可不要?为什么呢?
{
int count = this.Count;
this.Clear();
return count;
}
}
//为什么在这里重写 ,这个new 可要可不要?为什么呢
加了才是出现 警告!警告:
说明:成员“委托_只有一个订阅者.intList.RemoveAll()”不会隐藏继承的成员。不需要关键字 new。
文件:D:\data\asp\LinqTo\委托 只有一个订阅者\Program.cs
行:33
列:19
项目:我的测试
如下:
{
public A(int number)
{
this.Number = number;
}
public int Number { get; private set; }
public virtual int NumberV { get { return this.Number; } }
}class A10 : A
{
public A10(int number)
: base(number){}
public new int Number { get { return base.Number * 10; } }
public override int NumberV { get { return this.Number; } }
}class Program
{
static void Main(string[] args)
{
List<A> listA = new List<A>();
List<A10> listA10 = new List<A10>();
A10 a = new A10(1);
listA.Add(a);
listA10.Add(a); Console.WriteLine("listA:");
foreach (var item in listA)
{
Console.WriteLine("Number:" + item.Number);
Console.WriteLine("NumberV:" + item.NumberV);
} Console.WriteLine("listA10:");
foreach (var item in listA10)
{
Console.WriteLine("Number:" + item.Number);
Console.WriteLine("NumberV:" + item.NumberV);
} Console.ReadKey();
}
}
virtual主要针对某一个函数
再次阐述我的观点:----(不知对不对,请知道的网友指正) 1.不用声明virtual 来声明基类,在子类直接用new 方式 来重写.
2.基类用声明virtual 来声明,在子类用override 方式 来重写.请问:
这两个子类的以上两种重写结果 是一样的?编辑器出的内部代码也没有不同?
abstract:修饰的类是抽象类,修饰的方法是抽象方法。抽象类中可以定义抽象方法,也可以定义普通方法,但是定义的抽象方法必须在子类中进行重写,否则会报错。override是对父类方法的重写。而new是方法隐藏,此关键字可要可不要。如果在父类中有个方法,在子类中也有一个一模一样方法并且用new修饰,当实例化时,比如:
Person p=new Student();
p.work();
此时这个方法调用的是父类的方法不是子类的方法。
1、 virtual 虚则实之
2、 abstract 大而化之
abstract是抽象的方法 不能有实现,只能通过重写new 与override
override就是重写virtual的关键字,可以表现出多态,多态是面象对的编程的一部他
而new就是不表现多态的部份,从字面意思上理解也就是全是新的,是你写的子类的全新方法,也父类没有关系 。
override 与可以重写virtual.
首选abstract必须被重写,也就是继承了就必须重写 所以怎么会出现没有就用new 的说法的。所以这里的new 是对 virtual方法而言的,只是对象全新的,不表现多态的说明
//在公司上网,不方便,只能手写代码 大概如下
class Program
{
static void Main(){
Base a=new A();
Base b=new B();
a.Work();
b.Work();A a1=new A();
a1.Work();
Console.Read();
}
}public class Base{
public virtual void Work{Console.WriteLine("Base Write...")}
}public class A:Base{
public new void Work(){Console.WriteLine("A Wirte ...New");}
}public class B:Base{
public override void Work(){Console.WriteLine("A Wirte... override");}
}