博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于继承的问题
阅读量:5905 次
发布时间:2019-06-19

本文共 2821 字,大约阅读时间需要 9 分钟。

——摘自Rocky Ren

本文意在巩固基础知识,并不是对其进行深入剖析,如若对各位高手没有什么作用,请绕过。

本文为原创文,所有示例均是博主测试过的,欢迎大家批评指正,如有转载请标明出处,谢谢。
继承、封装和多态是面向对象编程的重要特性。
其成员被继承的类叫基类也称父类,继承其成员的类叫派生类也称子类。

派生类隐式获得基类的除构造函数和析构函数以外的所有成员。

派生类只能有一个直接基类,所以C#并不支持多重继承,但一个基类可以有多个直接派生类。

继承是可以传递的。即:

如果 ClassB 派生出 ClassCClassA 派生出 ClassB,则 ClassC 会继承 ClassB 和 ClassA 中声明的成员。

 

 class A

    {
        public void Sum(int i,int j)
        {
            int sum = i + j;
            Console.WriteLine("I am A ,my sum ={0}",sum);
        }
    }
    class B : A
    {
        public void Minus(int i,int j)
        {
            int minus = i - j;
            Console.WriteLine("I am B ,my minus ={0}", minus);

            this.Sum(3, 4);

        }

    }
    class InheritanceTest1
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.Minus(3, 4);
            Console.Read();
        }
    }

结果:I am B ,my minus=-1 

     I am A ,my sum = 7

 

试想一下,当基类Sum()方法是私有时,派生类还会继承该方法吗?

经过本人测试,没有在B类找到该方法,那么是不是它就没有被继承呢?其实不是的,私有成员其实已经被继承了,
但是它们却不可以被访问,因为私有成员只能被声明它们的类或结构体中才可访问,所以看上去像是没有被继承。
如果我们想降低访问基本,我们可以把基类Sum()方法定义为protected
能够阻止某个类被其他类继承吗?
答案是可以的,C#提供了一个sealed 修饰符,此修饰符会阻止其他类从该类继承。

 

    sealed class A

    {
        int test;
        public void Sum(int i,int j)
        {
            int sum = i + j;
            Console.WriteLine("I am A ,my sum ={0}",sum);
        }
    }
    class B : A 
    {
        public void Minus(int i,int j)
        {
            int minus = i - j;
            Console.WriteLine("I am B ,my minus ={0}", minus);
            this.Sum(3, 4);       //编译器会报错     
        }
     }

 

 前面说过,派生类隐式获得基类的除构造函数和析构函数以外的所有成员。

 那么我们该如何获得基类的构造函数和自身的构造函数呢?
 我们知道基类的初始化工作由基类的构造函数完成,派生类的初始化工作则有派生类的构造函数完成,
但是这样就产生了派生类构造函数的执行顺序问题。
当基类没有构造函数,派生类也没有构造函数时,派生类新曾成员的初始化工作由其他公有函数来完成。

 

 public  class A

    {
        int test=0;
        public void sum()
        {
            test++;
            Console.WriteLine("I am test ={0}" ,test);
        }
    }
    class B : A 
    {
        int i;
        public void PrintInt()
        {
            i = 3;
            Console.WriteLine("I am i ={0}", i);
        }
    }
    class InheritanceTest1 
    {
        static void Main(string[] args)
        {
            B b = new B();
            b.PrintInt();
            Console.Read();
        }
    }

结果:I am i=3 

 

 

如果只有派生类定义构造函数时,只需构造派生类对象即可。对象的基类部分使用默认构造函数来自动创建。

当基类和派生类都定义有构造函数时,那么执行顺序会怎样呢?

如果基类中是没有参数的构造函数,那么他可以隐式的被派生类执行,也就是说,派生类根本不需要包含构造函数

如果基类中是没有参数的构造函数,在派生类中可以自定义有参数的构造函数

 

public  class A

    {
        int test=0;
        public A()
        {
            test = 5;
            Console.WriteLine("I am A 公有默认构造函数 test={0}", test);
        }
    }
    class B : A 
    {
    }
    class InheritanceTest1 
    {
        static void Main(string[] args)
        {
            B b = new B();
            Console.Read();
        }
    }

结果:I am A 公有默认构造函数 test=5

 

由此可以看见,基类的构造函数被执行,在派生类中被调用。

如果基类定义了带有参数的构造函数,那么此构造函数必须被执行,且在派生类中实现该构造函数,此时我们可以使用base关键字

 

    class A

    {
        int test=0;
        public A(int i)
        {
            test = i;
            Console.WriteLine("I am A 公有有参构造函数 test={0}", test);
        }
    }
    class B : A 
    {
        public B(int j):base(j)
        {
            Console.WriteLine("I am B 公有有参构造函数,j={0}",j);
        }
    }
    class InheritanceTest1 
    {
        static void Main(string[] args)
        {
            B b = new B(1);
            Console.Read();
        }
    }

结果:I am A 公有有参构造函数 ,test=1     

     I am B 公有有参构造函数,j=1

 

 

由此可见: 派生类隐式执行基类中带有参数的构造函数,在程序中基类定义了带有参数的构造函数,

在其派生类中被继承,并使用base关键字调用基类中的构造函数来传送参数。

我们可以从代码中看到在创建派生类的对象后,程序首先运行的是基类的构造函数中的内容,然后才是派生类中的内容。

如果派生类的基类也是派生类,则每个派生类只需负责其直接基类的构造,不负责间接基类的构造,

并且其执行构造函数的顺序是从最上面的基类开始的,直到最后一个派生类结束。

 

转载于:https://www.cnblogs.com/zhuyuan28/p/3913344.html

你可能感兴趣的文章
利用POST重启路由器,一直无法实现,求帮助
查看>>
Mega Dropdown - 带子分类的响应式下拉菜单
查看>>
解决Windows服务修改配置文件后必须重启的问题
查看>>
vim如何进行分屏操作
查看>>
用nginx做反向代理来访问防外链图片
查看>>
mysql错误Table ‘./mysql/proc’ is marked as crashed and should be repaired
查看>>
黑马程序猿_2014 7月 我使用多线程体验
查看>>
MyBatis学习门户网站(一)
查看>>
分享毕业学生“ERP实施project联赛”总结,是肺腑之言——知识是人的价值的体现,每门课程是有意义的学校纪律...
查看>>
提高团队代码质量
查看>>
数字语音信号处理学习笔记——同态处理语音信号(1)
查看>>
Java 之外,是 Scala 还是 Groovy?【转载】
查看>>
题注Oracle数据库的网络连接原理
查看>>
dapper+linq+json+ztree构建树
查看>>
C#中string.Format()和ToString()格式化方法
查看>>
java interface的两个经典用法
查看>>
hessian入门
查看>>
跑ssis分组差错:没有关联“”。假设无法找到一个特定的连接元件,Connections 这种错误发生的收集...
查看>>
android listview item取消按点击效果
查看>>
RelativeLayout相对布局 各个属性详解
查看>>