C#入门02:最爱红烧肉-类

封装

C#中类的访问级别分为public,protected,private,Internal和protected Internal.Internal的做用是限制访问该类只能在当前程序集中,就是只能在当前dll库或当前exe程序中,意味着其余的程序集不能从该类派生子类来实现。C#和C++的封装区别还在于,C++使用public:来限定后面的语句都是在同一个做用域内,而C#的限定符只对当前语句有效,须要为每一个成员和方法都声明做用域,若是不使用显示声明,就使用默认的做用域。
class默认为Internal做用域,成员和方法默认是Private做用域编程

//public表示该类能够在任何地方被派生或调用
    //Internal表示该类只能在本程序集中被派生或调用
    //protected表示只能被子类派生或在子类中被调用
    //默认是Internal做用域,该类只能在本程序集中使用
    public class MyClass
    {
        //成员变量默认都是private,只能在本类使用,派生类或外部都不能够访问
        int age = 30;
        string name = "zhangsan";

        //成员方法默认也是private,不能被外部访问,须要显示添加public才能访问
        public void Print()
        {
            Console.WriteLine("name = {0}, age = {1}", name, age);
        }

        //声明static表示静态方法,和C++相似,能够使用类做用域访问
        //由于是public,因此能够在外部使用MyClass.sPrint()访问
        static public void sPrint()
        {
            Console.WriteLine("This is static function!");
        }
    }
   
    //类的建立都使用new方法,这点和C++有很大区别
    MyClass obj = new MyClass();
    obj.Print();
    
    //访问类的静态public方法
    MyClass.sPrint();

继承

多重继承指的是一个类别能够同时从多于一个父类继承行为与特征的功能。与单一继承相对,单一继承指一个类别只能够继承自一个父类。
C# 不支持多重继承。可是,您能够使用接口来实现多重继承。
C#派生类必须实现和基类一致的构造函数。
好比基类有base(int,int)这样的构造函数,那么在派生类中也必需要实现一样的subclass(int,int)构造函数。ide

//接口1
    public interface PaintCost
    {
        int getCost(int area);
    }

    //接口2
    public interface CalArea
    {
        int getArea();
    }

    //基类实现
    class Shape
    {
        //基类构造函数
        protected Shape(int w, int h)
        {
            width = w;
            height = h;
        }

        //基类方法1
        public int GetWidth()
        {
            return width;
        }

        //基类方法2
        public int GetHeight()
        {
            return height;
        }

        //基类成员,声明为protected能够被子类使用
        protected int width;
        protected int height;
    }

    // 派生类
    class Rectangle : Shape, PaintCost, CalArea
    {
        //子类构造函数,调用了基类的构造函数
        //必须实现和基类一致的构造函数,好比基类有base(int,int)这样的构造函数
        //那么在派生类中也必需要实现一样的subclass(int,int)构造函数
        public Rectangle(int w, int h) : base(w, h)
        {
        }

        //实现接口1的方法
        public int getCost(int area)
        {
            return area * (width + height) ;
        }

        //实现接口2的方法
        public int getArea()
        {
            return (width * height);
        }
    }

    //建立派生类的对象
    Rectangle rect = new Rectangle(20, 30);

    //打印方法输出
    Console.WriteLine("Cost={0}, Area={1}", rect.getCost(100), rect.getArea());

    //分别获取基类引用,接口1和接口2的引用
    //这里相似C++中的子类到基类的类型转换:
    //C++: base* b = subclass;
    PaintCost cost = rect;
    CalArea cal = rect;
    Shape sh = rect;

    //从接口1打印
    Console.WriteLine("PaintCost.Cost={0}", cost.getCost(100));

    //从接口2打印
    Console.WriteLine("CalArea.Area={0}", cal.getArea());

    //从基类打印成员
    Console.WriteLine("Shape.width={0}, Shape.height={1}", sh.GetWidth(), sh.GetHeight());

    //也能够使用as关键字来进行类型转换
    Shape sh2 = rect as Shape;

    //基类到派生类的转换:
    //C++:subclass* sub = dynamic_cast<base>(base);
    //if (sub != nullptr) 须要作一下判断是否转换成功
    Rectangle rect2 = sh as Rectangle;
    if (rect2 != null)
    {
        //须要作一下判断,转换失败rect2为空,但不会抛出异常
    }

多态

多态性意味着有多重形式。在面向对象编程范式中,多态性每每表现为"一个接口,多个功能"。多态性能够是静态的或动态的。在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。在编译时,函数和对象的链接机制被称为早期绑定,也被称为静态绑定。函数

静态多态性
C# 提供了两种技术来实现静态多态性。分别为:函数重载和运算符重载。
C#的函数重载和C++相似,运算符重载将在下一节专门说明。code

动态多态性
C#动态多态性是经过抽象类和虚方法实现的。
抽象类使用关键字abstract来声明。
虚方法使用关键字virtual来声明。
派生类中使用override来重载基类的抽象方法和虚方法。
一、抽象类
您不能建立一个抽象类的实例。 您不能在一个抽象类外部声明一个抽象方法。 经过在类定义前面放置关键字 sealed,能够将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。对象

//抽象类abstract
    abstract class Shape
    {
        //抽象方法abstract
        public abstract int area();
    }

    class Rectangle : Shape
    {
        //实现抽象方法override
        public override int area()
        {
            throw new NotImplementedException();
        }
    }

二、虚方法
当有一个定义在类中的函数须要在继承类中实现时,能够使用虚方法。虚方法是使用关键字 virtual 声明的。虚方法能够在不一样的继承类中有不一样的实现。对虚方法的调用是在运行时发生的。继承

class Shape
    {
        //基类虚方法,有本身的实现
        public virtual int area()
        {
            Console.WriteLine("父类的面积:");
            return 0;
        }
    }

    class Rectangle : Shape
    {
        //派生类重载虚方法,实现本身的订制化功能
        public override int area()
        {
            Console.WriteLine("Rectangle 类的面积:");
            return (width * height);
        }
    }

运算符重载

class Box
    {
        // 重载 + 运算符来把两个 Box 对象相加
        public static Box operator +(Box b, Box c)
        {
            Box box = new Box();
            box.length = b.length + c.length;
            box.breadth = b.breadth + c.breadth;
            box.height = b.height + c.height;
            return box;
        }
    }

    Box Box1 = new Box();         // 声明 Box1,类型为 Box
    Box Box2 = new Box();         // 声明 Box2,类型为 Box
    Box Box3 = new Box();         // 声明 Box3,类型为 Box

    // ...

    // 把两个对象相加
    Box3 = Box1 + Box2;

    //特别说明:
    //这里Box3能够不用new Box()操做
    //若是有new操做,那么上面的操做实际上是赋值操做,将Box1+Box2产生的Box对象拷贝给Box3
    //若是没有new操做,那么Box3其实是Box1+Box3产生的Box对象的引用类型
    //前者是新的对象产生,会花费更多时间和空间,后者更快,可是共享内存空间,若是该内存空间不会
    //被其余地方使用,那么没有任何问题,若是有被其余使用,就可能引起其余问题。

    //常见的运算符重载
    public static Box operator +(Box b, Box c);
    public static bool operator ==(Box lhs, Box rhs);
    public static bool operator !=(Box lhs, Box rhs);
    public static bool operator <(Box lhs, Box rhs);
    public static bool operator >(Box lhs, Box rhs);
    public static bool operator <=(Box lhs, Box rhs);
    public static bool operator >=(Box lhs, Box rhs);
    public override string ToString();

接口

抽象类在某种程度上与接口相似,可是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。接口使用 interface 关键字声明,它与类的声明相似。接口声明默认是 public 的。
**C#仅支持单一继承,但能够实现多个接口。 **
接口也能够被继承,实现类必须实现继承链上的全部接口方法接口

//接口1
    interface IParentInterface
    {
        void ParentInterfaceMethod();
    }

    //接口2继承接口1
    interface IMyInterface : IParentInterface
    {
        void MethodToImplement();
    }

    //实现类继承接口2,所以必须实现接口1和接口2的全部方法
    class InterfaceImplementer : IMyInterface
    {
        //实现接口1的方法
        public void ParentInterfaceMethod()
        {
            Console.WriteLine("ParentInterfaceMethod() called.");
        }

        //实现接口2的方法
        public void MethodToImplement()
        {
            Console.WriteLine("MethodToImplement() called.");
        }
    }
相关文章
相关标签/搜索