面向对象学习之二:继承

发布时间:2020-10-07 00:19:23 作者:yuan469
来源:网络 阅读:581

面向对象学习之二:继承

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。这样可以实现一个重写方法,同时借用基类的实现。


推荐阅读:
  1. 面向对象-继承与派生
  2. Python面向对象特性 - 继承

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

继承 隐式转换 成员隐藏

上一篇:Log4j日志输出详解

下一篇:详解SqlServer数据库中Substring函数的用法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》