扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
面向对象学习之二:继承
成都创新互联公司是一家专业从事网站制作、网站建设、网页设计的品牌网络公司。如今是成都地区具影响力的网站设计公司,作为专业的成都网站建设公司,成都创新互联公司依托强大的技术实力、以及多年的网站运营经验,为您提供专业的成都网站建设、营销型网站建设及网站设计开发服务!1、成员的可访问性:
访问修饰符 | 意义 |
public | 成员定义范围的外部和内部都是完全可见的,即对公共成员的访问不受限制。 |
protected | 成员仅对定义类及其派生类可见。 |
internal | 成员在包含它的程序集内部的任何地方可见,这包括定义在类以及程序集内定义类之外的任何范围。 |
private | 成员只在定义类内可见,这是最严格的访问形式,是类成员默认的访问级别。 |
2、成员隐藏:
继承可以扩展功能,但不能移除功能,例如,基类里可用的公共方法,在派生类及派生类的派生类的实例里都是可用的。不能从派生类中移除这些功能。请看下面代码:
namespace 隐藏成员 { public class A { public void DoSomething() { Console.WriteLine("A.DoSomething"); } } public class B : A { public new void DoSomething() { Console.WriteLine("B.DoSomething"); } public void DoSomethingElse() { Console.WriteLine("B.DoSomethingElse"); } } class Program { static void Main(string[] args) { B b = new B(); b.DoSomething(); b.DoSomethingElse(); A a = b; a.DoSomething(); Console.ReadKey(); } } }
分析:
程序运行结果为:
虽然类B隐藏了类A的DoSomething实现,但并没有移除它,只是在通过B引用来调用的时候隐藏了。在Main方法中可以看到,可以轻松的绕过这一点。通过隐式转换把B实例引用转换成A实例引用,就可以通过A实例引用来调用A.dosomething的实现。因此A.dosomething并没有丢掉,而是隐藏了,需要多做一点工作来找到它。
3、override和new方法:
在派生类中重写方法,必须用override修饰符来标记方法。否则,编译器会提示警告,要求在派生方法中提供new修饰符或override。而且,编译器默认使用new修饰符,看看下面的代码:
namespace 继承和虚方法 { public class A { public virtual void SomeMethod() { Console.WriteLine("A.SomeMethod"); } } public class B : A { public void SomeMethod() { Console.WriteLine("B.SomeMethod"); } } class Program { static void Main(string[] args) { B b = new B(); A a = b; a.SomeMethod(); Console.ReadLine(); } } }
分析:
运行结果是:调用A.SomeMethod。
New关键字打破了这个层次结构中的虚函数链。当一个虚方法通过对象引用调用的时候,调用的方法取决于运行时的方法表,如果方法是虚的,运行时会搜索层次结构寻找方法在继承体系中最底层的派生版本,然后调用它(这里是类B)。但是,如果在搜索过程中遇到一个标有new修饰符的方法,它会退回继承体系中的上一级类(这里是类A),并使用这个类中的方法。由于C#在new和override都不存在的情况下默认使用new修饰符,这就是为什么A.SomeMethod被调用的原因。
如果B.SomeMethod标记为override,这段代码就会调用B.SomeMethod。
4、Base关键字:base允许访问一个实例的基类实现,看看下面代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 继承 { public class A { private int x; public A(int var) { this.x = var; } public virtual void DoSomething() { Console.WriteLine("A.DoSomething"); } } public class B : A { public B():base(123) { } public override void DoSomething() { Console.WriteLine("B.DoSomething"); base.DoSomething(); } } class Program { static void Main(string[] args) { B b = new B(); b.DoSomething(); Console.ReadKey(); } } }
分析:
本例中可以看到两处使用base关键字,
第2个地方是B.DoSomething实现,在类B的实现中,实现B.DoSomething的时候借用类A中的A.DoSomething实现,因此,可以在B.DoSomething实现内通过base关键字直接调用A.DoSomething。
通常,调用实例的虚方法会调用虚方法最底层的实现,也就是B.DoSomething。但是,如果通过base关键字调用,就会调用基类最底层的的派生方法。因为A是基类,A.DoSomething是DoSomething相对于类A的基类方法,因此base.DoSomething就会调用A.DoSomething。这样可以实现一个重写方法,同时借用基类的实现。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流