天天看点

C#的继承、接口、抽象类理解

OOP三特性:继承、封装、多态

继承:C#属于单继承,即派生类最多只能有一个直接基类,但可以传递继承,即A类派生B类,B类派生C类,派生类会保留所有基类以及传递基类的字段、属性、方法等所有内容。如果要在派生类中隐藏基类内容,可以通过new关键字实现,或是通过base来调用基类的内容

传递继承示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 继承
{
    public class Program
    {
        public class A
        {
            public string _fieldA = "A类字段";
            public int PropertyA { get; set; }
            //如果要提供一个示例方法,则使用virtual关键字修饰,派生类如果不重写virtual方法,则使用基类提供的virtual方法,且必须有对应的实现,重写则使用重写方法
            //如果只提供一个规范,则使用abstract关键字,注意abstract方法只能在abstract类中使用,而且没有任何实现,且必须在派生类中重写,除非派生类也是抽象类(抽象派生类会直接继承抽象方法而不实现)
            public virtual void FuncA() 
            {
                Console.WriteLine("A类示例方法FuncA");
            }
        }
        public class B : A
        {
            public string _fieldB = "B类字段";
            public override void FuncA()
            {
                Console.WriteLine("重写A类方法");
            }
        }
        public class C : B
        {
            public string _fieldC = "C类字段";
        }

        static void Main(string[] args)
        {
            C c = new C();
            Console.ReadKey();
        }
    }
}
           

传递继承如图,实例方法的调用必须基于有一个对象,而静态方法不属于对象,可以直接调用。

C#的继承、接口、抽象类理解

抽象类:使用abstract关键字创建不完整且必须在派生类中实现的类和class成员。使用sealed可以防止继承以前标记为virtual的类或某些成员。抽象类用于继承,故隐式的为public,且不可被private、protected、internal修饰。

注意:1.基类virtual方法若不在派生类中override重写,则对派生类实例调用会使用基类的virtual方法,相当于预定义

          2.若基类virtual方法在派生类override重写,则对派生类实例调用会使用重写的override方法

          3.抽象方法只能在抽象类中修饰,且没有实现,结束时一个分号,必须在派生类中override实现

接口:      

          1.由于C#是单继承,要实现多重继承可以通过接口实现,C#接口不能有public、private、internal、protected修饰符,接口隐式public

          2.如果接口继承接口,子接口有与父接口同名方法,可以new隐藏父接口方法

          3.接口无构造函数,不能new来实例化,接口一旦实现,实现类中必须实现接口所有方法,除非实现类是抽象类

区别:接口更多的表是一种can-do的规范,多用于实现多重继承,且与继承类关系并不紧密。抽象则类似于IS-A关系,与继承类关系较为紧密。抽象类不可以new,不可以sealed,接口中继承父接口的子接口可以通过new来重写覆盖同名父方法。两者都不可以使用private、protected、internal修饰。接口通常用于规范行为,而抽象类是对对象的模拟,例如C#和java都实现oop接口,但C#是MS抽象类,java是sun抽象类

接口示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 接口和集合
{
    class Program
    {
        //接口解释和用途:
        //⑴由于C#是单继承,要实现多重继承可以通过接口实现,C#接口不能有public、private、internal、protected修饰符,接口隐式public
        //⑵如果接口继承接口,子接口有与父接口同名方法,可以new隐藏父接口方法
        //⑶接口无构造函数,不能new来实例化,接口一旦实现,实现类中必须实现接口所有方法,除非实现类是抽象类

        //账户接口1:通用
        public interface IBankGeneralCustomer
        {
            //存钱
            void Save(double _payMoney);
            //取钱
            bool Withdraw(double _withdrawMoney);
            //余额
            void Surplus(double _surplusMoney);
        }
        //账户接口2:土豪专用
        public interface IBankTuhaoCustomer
        {
            //土豪提醒
            void startReminder(string message);
            void endReminder(string message);
        }
        //屌丝客户
        public class LiaoRan:IBankGeneralCustomer
        {
            public double  balance { get; set; }

            public void Save(double _payMoney)
            {
                balance = balance + _payMoney;
            }
            public bool Withdraw(double _withdrawMoney)
            {
                if (balance - _withdrawMoney <= 0)
                    return false;
                else
                {
                    balance = balance - _withdrawMoney;
                    Console.WriteLine("取出{0}剩余{1}", _withdrawMoney, balance);
                    return true;
                }
            }
            public void Surplus(double _surplusMoney)
            {
                Console.WriteLine("余额{0}", balance);
            }
        }
        //土豪客户
        public class Guhao:IBankGeneralCustomer,IBankTuhaoCustomer
        {
            public double balance { get; set; }

            public void Save(double _payMoney)
            {
                balance = balance + _payMoney;
            }
            public bool Withdraw(double _withdrawMoney)
            {
                if (balance-_withdrawMoney <= 0)
                    return false;
                else
                {
                    balance = balance - _withdrawMoney;
                    Console.WriteLine("取出{0}剩余{1}", _withdrawMoney, balance);
                    return true;
                }
            }
            public void Surplus(double _surplusMoney)
            {
                Console.WriteLine("余额{0}", balance);
            }
            public void startReminder(string message)
            {
                Console.WriteLine("交易开始{0}",message);
            }
            public void endReminder(string message)
            {
                Console.WriteLine("交易结束{0}",message);
            }
        }
        static void Main(string[] args)
        {
            LiaoRan lr = new LiaoRan();
            lr.Save(50.00);
            lr.Withdraw(49.00);
            Guhao gh = new Guhao();
            gh.startReminder("1号台");
            gh.Save(100.00);
            gh.Withdraw(20.00);
            gh.endReminder("2号台");
            Console.ReadKey();
        }
    }
}