c#面向对象- 继承

概念:

个人理解:

 在一些类中,写一些重复成员,我们可以将这些重复的成员,单独封装到一个类中,作为这些类的父类。

最终目的:解决类与类之间的代码冗余!!!

说明下:

在实际开发中,会把不同的类写到类文件中去,这里是为了演示方便写到一起了。

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            Son son = new Son();
            // 之所以Son类可以访问到Person类的属性,因为Son类继承了Student类
            // 而Student类继承了Person类,可以间接继承。
            son.Age = 20;
        }
    }
    // Person类就是一个公共类、父类又叫基类
    public class Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        private int _age;
        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }
    }
    // Student类/派生类,继承了Person类
    public class Student: Person
    {
        private int _height;
        public int Height
        {
            get { return _height; }
            set { _height = value; }
        }
    } 
    // Son继承了Person类
    public class Son: Student
    {
    
    }
}

 

注意:

(1)子类不会继承父类的私有字段,因为访问不到!

(2)子类并没有继承父类的构造函数,但是,子类会默认先调用父类无参的构造函数,创建父类对象;之所以要先调用父类的无参构造函数,因为只有父类对象创建出来了,子类才能使用父类中的成员;

如果在父类中重写了一个有参数的构造函数,那么,那个无参的构造函数将会被干掉,子类就调用不了父类成员了,所以会导致子类报错!!!

解决办法:1> 在父类中手动的重新写一个无参数的构造函数  ( 在下边有对应例子 );

                  2>  在子类中显示的调用父类的构造函数,使用关键字 :base( )    

下边例子中,子类继承父类,当new 子类时,父类无参构造函数会先执行,把父类创建出来,然后子类的构造函数,才会执行,这个也很容易理解,从思维逻辑上讲一点毛病都没有!

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            Student son = new Student();
        }
    }
    public class Person
    {
        public Person()
        {
            Console.WriteLine("person");
            Console.ReadKey();
        }
    }
    public class Student: Person
    {
        public Student()
        {
            Console.WriteLine("student");
            Console.ReadKey();
        }
    }
}

 对应上边解决方法一(在父类中在写一个无参的构造函数):

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            Student son = new Student();
        }
    }
    public class Person
    {
        public string _name = "LVXINGCHEN";
        public Person(string name)
        {
            Console.WriteLine("person");
            Console.ReadKey();
        }
        // 重新写一个无参的构造函数,此时,子类不会报错了,且当子类被调用时,父类对象将会被创建
        public Person()
        {

        }
    }
    public class Student: Person
    {
        public Student()
        {
            Console.WriteLine("student");
            Console.ReadKey();
        }
    }
}

 对应上边解决方法二(使用:base( ))

下边,我们对子类使用了 :base(), 来调用父类有参数的构造函数,从而创建父类对象。

输出结果:

namespace ConsoleApp6
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student("吕星辰", 20);
        }
    }
    public class Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public Person(string name, int age)
        {
            // 在构造函数中访问本类的属性使用this
            this.Name = name;
            Console.WriteLine($"{name}, {age}");
            Console.ReadKey();
        }
    }
    public class Student: Person
    {
        public Student(string name, int age):base(name, age)
        {

            Console.WriteLine("student");
            Console.ReadKey();
        }
    }
}

 

继承的特性:

(1)继承的单根性:一个子类只能继承一个父类;

(2)继承的传递性:一个子类只能继承一个父类

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值