C# 面向对象总结

C# 面向对象总结

导图


C# 面向对象总结_第1张图片

namespace _03面向对象练习{    class Program    {        static void Main(string[] args)        {        }    }    class Person    {        // 字段、属性、函数、构造函数        // 字段:存储数据        // 属性:用于保护字段        // 函数:描述对象的行为        // 构造函数:初始化对象,给对象的每个属性赋值        string _name;        public string Name        {            get            {                return _name;            }            set            {                _name = value;            }        }        int _age;        public int Age        {            get            {                return _age;            }            set            {                _age = value;            }        }        public char Gender { get; set; }        public Person(char gender)        {            if (gender != '男' && gender != '女')            {                gender = '男';            }            this.Gender = gender;        }    }}

Demo4:三个关键字

C#中的三个关键字:

new

1. 创建对象

---在堆中开辟空间

---在开辟的堆空间中创建对象

---调用对象的构造函数

2. 隐藏父类的成员

this

1. 代表当前类的对象

2. 显式的调用自己的构造函数

base

1. 显式调用父类的构造函数

2. 调用父类的成员

namespace_04三个关键字{classProgram{staticvoidMain(string[]args){}}classPerson{publicvoidSayHello(){Console.WriteLine("我是人类");}}classStudent:Person{// new的作用是显式告诉编译器SayHello已经覆盖了父类的SayHello函数,若不加new会有警告信息publicnewvoidSayHello(){Console.WriteLine("我是学生");}publicStudentGetStudent(){returnthis;}// base代表父类(不是父类对象)publicvoidPersonSayHello(){base.SayHello();}}classTeacher{publicstringName{get;set;}publicint  Age{get;set;}publicchar Gender{get;set;}publicint Chinese{get;set;}publicint Math{get;set;}publicint English{get;set;}// 构造函数publicTeacher(stringname,int age,char gender,int chinese,int math,int english){this.Name=name;this.Age=age;this.Gender=gender;this.Chinese=chinese;this.Math=math;this.English=english;}// this:显式调用自己的构造函数publicTeacher(stringname,int age,char gender):this(name,age,gender,0,0,0){}publicTeacher(stringname,int chinese,int math,int english):this(name,0,'\0',chinese,math,english){}}}

Demo5:多态的实现

面向对象的三大特性:

封装:

---减少了大量的冗余代码

---封装功能,对外提供简单的接口

继承:

---减少了类中的冗余代码

---让类之间产生了关系,为多态打下基础

继承的特性:

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

---传递性:B继承A,C继承B,C可以访问A

里氏转换:(子类和父类之间可以相互转化,这就是多态的基础)

---子类可以赋值给父类

---如果父类中装的是子类对象,则可以将这个父类转换为对应的子类对象

---关键字

---is:返回bool类型,指示是否可以做这个转化

---as:如果转化成功,则返回对象,否则返回null

作用:我们可以将所有的子类都当作父类来看,针对父类进行编程,写出通用的代码,适应需求的不断改变。

多态:

---虚方法

virtual override

---抽象类

abstract override

---接口

interface

namespace _05动物类继承{    class Program    {        static void Main(string[] args)        {            // 实现多态:声明父类去指向子类对象            Animal[] a = { new Cat(), new Dog() };            for(int i = 0; i < a.Length; i++)            {                a[i].Bark();                a[i].Drink();                a[i].Eat();            }        }    }    abstract class Animal    {        // 抽象成员只能存在于抽象类中        public abstract void Bark();//父类没办法确定子类如何实现,因此不能写具体实现        public void Eat()        {            Console.WriteLine("动物舔着吃");        }        public void Drink()        {            Console.WriteLine("动物舔着喝");        }    }    class Cat : Animal    {        public override void Bark()        {            Console.WriteLine("猫咪喵喵叫");        }    }    class Dog : Animal    {        public override void Bark()        {            Console.WriteLine("狗汪汪叫");        }    }}

Demo6:里氏转换

namespace _06里氏转换{    class Program    {        static void Main(string[] args)        {            Person person = new Student();            /*            if (person is Teacher)            {            }            */            Student student = person as Student;// 将person转化为student对象            if (student != null)            {                student.StudentSayHello();            } else            {                Console.WriteLine("转换失败");            }        }    }    class Person    {        public void PersonSayHello()        {            Console.WriteLine("我是父类");        }    }    class Student : Person    {        public void StudentSayHello()        {            Console.WriteLine("我是学生");        }    }    class Teacher : Person    {        public void TeacherSayHello()        {            Console.WriteLine("我是老师");        }    }}

Demo7:virtual和override

若不加virtual和override关键字时

namespace _07虚方法{    class Program    {        static void Main(string[] args)        {            BaseClass baseClass = new BaseClass();            Derived derived = new Derived();            baseClass.PrintMethod();//输出base            derived.PrintMethod();//输出devired            baseClass = new Derived();            baseClass.PrintMethod();//输出base        }    }    class BaseClass    {        public void PrintMethod()        {            Console.WriteLine("base");        }    }    class Derived : BaseClass    {        public void PrintMethod()//此处有警告,因为覆盖了父类的方法,并且没有显式加new关键字        {            Console.WriteLine("derived");        }    }}

上述没有使用virtual和override的重写实际上起到了隐藏父类方法的作用

2.使用virtual和override的重写

namespace _07虚方法{    class Program    {        static void Main(string[] args)        {            BaseClass baseClass = new BaseClass();            Derived derived = new Derived();            baseClass.PrintMethod();//输出base            derived.PrintMethod();//输出devired            baseClass = new Derived();            baseClass.PrintMethod();//输出devired        }    }    class BaseClass    {        public virtual void PrintMethod()        {            Console.WriteLine("base");        }    }    class Derived : BaseClass    {        public override void PrintMethod()        {            Console.WriteLine("derived");        }    }}

解释如下:

BaseClass baseClass = new Derived();

上述语句,BaseClass叫做声名类,Derived叫做实例类

编译器具体的检查流程如下:

1.当调用函数时,系统直接检查声明类,查看所调用函数是否是虚函数

2.如果不是,直接执行该函数。若是virtual函数,转去检查实例类

3.在实例类中,若有override的函数,则执行,若没有,则依次上溯,对父类进行检查,直到找到第一个override了此函数的父类,然后执行

因此,若Derived类中没有override,则在BaseClass中执行同名函数

Demo8:抽象类

抽象类知识点:

抽象成员必须标记为abstract,并且不能有具体实现

抽象成员必须在抽象类中

抽象类不能被实例化

子类继承抽象类后,必须把父类中的所有抽象成员重写(若子类也是抽象类,则不用)

抽象成员的访问修饰符不能是private

抽象类中可以包含实例成员,并且抽象类中的实例成员可以不被子类实现

抽象类有构造函数,虽然不能被实例化

如果父类的抽象方法中有参数,则继承这个父类的子类在重写父类的方法时必须传入对应参数,返回值同理

若父类中的方法有默认的实现,并且父类需要被实例化,可以考虑将父类定义成一个普通类,用虚方法来实现多态若父类中的方法没有默认实现,父类也不需要被实例化,则可以定义为抽象类

namespace _08抽象类练习{    class Program    {        static void Main(string[] args)        {                    }    }    // 抽象类    abstract class MobileStorage    {        public abstract void Read();        public abstract void Write();    }    class Phone : MobileStorage    {        public override void Read()        {            Console.WriteLine("手机在读取数据");        }        public override void Write()        {            Console.WriteLine("手机在写入数据");        }    }    class MP3 : MobileStorage    {        public override void Read()        {            Console.WriteLine("MP3在读取数据");        }        public override void Write()        {            Console.WriteLine("MP3在写入数据");        }        public void PlayMusic()        {            Console.WriteLine("MP3在播放音乐");        }    }    class Computer    {        public MobileStorage MS        {            get;            set;        }        public void ComputerRead()        {            this.MS.Read();        }        public void ComputerWrite()        {            this.MS.Write();        }    }}

Demo9:接口的使用

接口知识点:

接口更多的表示一种规范,一种能力,功能要单一

一个类继承了一个接口,就必须实现这个接口的所有成员

接口不能被实例化

接口中的成员不能加访问修饰符,默认为public,不能修改

接口中的成员不能有任何实现

接口中只能有方法、属性、索引器、事件,不能有字段和构造函数

接口之间可以继承

实现接口的子类必须实现该接口的所有成员

一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,则语法上A必须写在IA前面

当一个抽象类实现接口时,需要子类去实现接口

namespace _09接口的使用{    class Program    {        static void Main(string[] args)        {            // 实现多态            IEat[] eaters = { new Student(), new Teacher() };            for (int i = 0; i != eaters.Length; i++)            {                eaters[i].Eat();            }                    }    }    class Person    {        public void PersonSayHello()        {            Console.WriteLine("Person:Hello!");        }    }    interface IEat    {        void Eat();    }    class Student : Person, IEat    {        public void Eat()        {            Console.WriteLine("Student:I Can Eat");        }    }    class Teacher: Person, IEat    {        public void Eat()        {            Console.WriteLine("Teacher:I Can Eat too");        }    }}

Demo10:显示实现接口

namespace _10显示实现接口

{

    class Program

    {

        static void Main(string[] args)

        {

        }

    }

    interface I

    {

        void Test();

    }

    class Person : I

    {

        public void Test()

        {

            Console.WriteLine("这个Test函数是属于Person的");

        }

        void I.Test()

        {

            Console.WriteLine("显示实现接口的Test函数");

        }

    }

}

你可能感兴趣的:(C# 面向对象总结)