【C#基础详解】(十四)面向对象 继承

面向过程:

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。

缺点:没有面向对象易维护、易复用、易扩展。

面向对象:

面向对象的三个核心要素是:封装、继承、多态。

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护。

缺点:性能比面向过程低。

面向过程的思维方式,它更加注重这个事情的每一个步骤以及顺序。他比较直接高效,需要做什么可以直接开始干。

面向对象的思维方式,它更加注重事情有哪些参与者,需求里面有哪些对象,这些对象各自需要做些什么事情。将其拆解成一个个模块和对象,这样会更易于维护和拓展。

13.1 继承的含义

1)什么是继承?

继承是在类之间建立一种相交关系,使得新定义的派生类(子类)的实例可以继承已有基类(父类)的特征和能力,而且还可以加入新的特性或者修改已有的特性建立起类的新层次。

注意:object是所有类的基类。

白话:我们可能会在一些类中,写一些重复的成员/方法,我们可以将这些重复的成员/方法,单独地封装到一个类中,作为这些类的父类。

例如:Person是父类(基类)

        Student、Teacher、Driver是子类(派生类)

2)继承的语法:

[public] class 子类类名:父类类名

public class Student:Person{ }

3)继承的作用

① 是在一些比较一般的类的基础上构造、建立和扩充新类的最有效的手段

② 简化了人们对事物的认识和描述,能清晰体现相关类间的层次结构关系。

③ 提供了软件复用功能,如果说类B继承类A,那么只需要在类B中添加类A中没有的类成员即可,这样能减小代码和数据的冗余度,大大的增加了程序的复用性。

④ 继承通过增强一致性来减少模块间的接口和界面,大大增加了程序的易维护性。

4)子类继承了什么

子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。

子类没有继承父类的构造函数,但是,子类会默认地调用父类的无参数的构造函数,创建父类对象,让子类可以使用父类中的成员。所以,如果在父类中重写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以子类会报错。

解决办法:

① 在父类中重新写一个无参数的构造函数。

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

13.2 继承的特点

1)继承的特点:

① 派生类是对基类的扩展,派生类可以添加新的成员,但不能移除已经继承的成员的定义。

② 继承可以传递。比如说类C继承类B,类B又继承类A,那么类C不但继承了类B声明的成员,同时也继承了类A声明的成员。

③ 构造函数和析构函数不能直接被继承,除此之外其他成员可以直接被继承。基类中成员的访问方式只能决定派生类中能否访问它们。

④ 派生类如果定义了与基类成员名相同的新成员,那么就可以覆盖基类中的成员。但是这并不是删除了这些成员,而是不能访问再它们而已。

new关键字:1.创建对象 2.隐藏从父类那里继承过来的同名成员,隐藏的后果就是子类调用不到父类的成员

⑤ 基类可以定义虚方法、虚属性及虚索引指示器,它的派生类可以重载这些成员,从而展示出它们的多态性。

⑥ 派生类中能从一个类中继承,可以通过接口来实现多重继承。

2)继承的特性:

单根性:一个子类只能有一个父类。

传递性:可以一个传递一个(爷爷传父亲,父亲传儿子)

 13.3 继承的练习

//1)创建父类:
    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; }
        }
        private char _gender;
        public char Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }
        public Person(string name,int age,char gender)
        {
            this.Name = name;
            this.Age = age;
            this.Gender = gender;
        }
    }

//2)创建Driver子类:
    public class Driver:Person
    {
        private int _driveTime;
        public int DriveTime
        {
            get { return _driveTime; }
            set { _driveTime = value; }
        }
        public void DriverSayHello()
        {
            Console.WriteLine("我叫{this.Name},我是司机,我年龄是{this.Age},我是{this.Gender}人,我的驾龄是{this.DriveTime}");
        }
        public Driver(string name,int age,char gender,int driveTime) : base(name, age, gender)
        {
            this.DriveTime = driveTime;
        }
    }

//3)创建Programmer子类:
    public class Programmer:Person
    {
        private int _workYear;
        public int WorkYear
        {
            get { return _workYear; }
            set { _workYear = value; }
        }
        public void ProgrammerSayHello()
        {
            Console.WriteLine("我叫{this.Name},是一个程序员,我年龄是{this.Age},我是{this.Gender}生,我的工作年限是{this.WorkYear}年");
        }
        public Programmer(string name,int age,char gender,int workYear) : base(name, age, gender)
        {
            this.WorkYear = workYear;
        }
    }

//4)创建Reporter子类:
    public class Reporter:Person
    {
        private string _hobby;
        public string Hobby
        {
            get { return _hobby; }
            set { _hobby = value; }
        }
        public void ReporterSayHello()
        {
            Console.WriteLine("我是{this.Name},我是记者,我的爱好是{this.Hobby},我是{this.Gender}生,我今年{this.Age}岁了");
        }
        public Reporter(string name,int age,char gender,string hobby) : base(name, age, gender)
        {
            this.Hobby = hobby;
        }
    }

//5)在Main函数调取:
static void Main(string[] args)
{
    Reporter r = new Reporter("zs", 22, '男',"拍照");
    r.ReporterSayHello();
    Programmer p = new Programmer("ls", 23, '男',4);
    p.ProgrammerSayHello();
    Driver d = new Driver("ww", 35, '男',15);
    d.DriverSayHello();
    Console.ReadKey();
}

输出结果:

我是zs,我是记者,我的爱好是拍照,我是男生,我今年22岁了

我叫ls,是一个程序员,我年龄是23,我是男生,我的工作年限是4年

我叫ww,我是司机,我年龄是35,我是男人,我的驾龄是15

13.3 里氏转换

1)含义:

① 子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替。

② 如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。

注意:子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。

例如:

Person p = new Student();

Student ss = (Student)p;

2)is关键词和as关键词:

① is:表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false。

if (p is Student)
{
    Student ss = (Student)p;
    ss.StudentSayHello();
}
else
{
    Console.WriteLine("转换失败");
}
Console.ReadKey();

② as:表示类型转换,如果能够转换则返回对应的对象,否则返回一个null。

Student t = p as Student;
t.StudentSayHello();
Console.ReadKey();

3)里氏转换练习:

    class Program
    {
        static void Main(string[] args)
        {
            //创建10个对象,通过个循环去调用他们各自打招呼的方法
            Person[] pers = new Person[10];  //Person的数组
            Random r = new Random();  //随机值
            for (int i = 0; i < pers.Length; i++)
            {
                int rNumber = r.Next(1, 5);
                switch (rNumber)//给数组赋值
                {
                    case 1:
                        pers[i] = new Student();
                        break;
                    case 2:
                        pers[i] = new Teacher();
                        break;
                    case 3:
                        pers[i] = new MeiLv();
                        break;
                    case 4:
                        pers[i] = new Person();
                        break;
                }
            }
            for (int i = 0; i < pers.Length; i++)
            {
                if (pers[i] is Student)
                {
                    ((Student)pers[i]).StudentSay();
                }
                else if (pers[i] is Teacher)
                {
                    ((Teacher)pers[i]).TeacherSay();
                }
                else if (pers[i] is MeiLv)
                {
                    ((MeiLv)pers[i]).MeiLvSay();
                }
                else
                {
                    pers[i].PersonSay();
                }
            }
            Console.ReadKey();
        }
    }
    public class Person
    {
        public void PersonSay()
        {
            Console.WriteLine("我是人类");
        }
    }
    public class Student : Person
    {
        public void StudentSay()
        {
            Console.WriteLine("我是学生");
        }
    }
    public class Teacher : Person
    {
        public void TeacherSay()
        {
            Console.WriteLine("我是老师");
        }
    }
    public class MeiLv : Person
    {
        public void MeiLvSay()
        {
            Console.WriteLine("我是美女");
        }
    }

输出结果:

是随机不同角色打招呼的十条语句

猜你喜欢

转载自blog.csdn.net/Y1RV1NG/article/details/130092868
今日推荐