• C#面向对象的一些东西


         最近在复习C#面向对象,也就是说常说的3大特性:封装、继承和多态。首先说一下封装,其实封装最大的目的也是为了实现代码的解耦和重用、代码也是安全的(对外它隐藏了具体的实现,就好比我们拿个遥控器就能操作电视机,而无须知道其内部实现);C#中很多地方都用到了封装,可以将一个具体的功能代码封装成一个方法,供外界调用就是一个封装。

         再说一下继承吧。首先要搞明白的是,继承是类与类之间的关系,那么必然有一个父类,一个子类(可以理解为父亲和儿子的关系),父类是相对子类更抽象的类,而子类是相对父类更具体的类(可以理解为父类能做的事儿,子类继承后都可以做,这里有一个特例,父类如果将一个方法或字段设为Sealed,私有的,子类是继承不到的;而子类能做的事儿,父类不一定能做,即在子类中新增的方法),C#有2种继承,体现为父类中有虚方法(virtual)父类是抽象类(abstract),这2种都可以供子类继承,根据2种实现时语法上的不同,他们的区别是:

    1.如果一个需求是很模糊,很广泛的,这是考虑抽象类,而不是虚方法。

    2.如果一个父类要求有代码实现,那么就必须用虚方法,因为抽象方法是不允许有代码实现的;

    3.如果强制要求一个子类必须实现父类中的方法,那么父类必须用抽象类,如果没有这样的要求,那么父类可以用虚方法;

    4.抽象类不能被实例化(但可以有构造函数),可以有实例成员也可以有抽象成员。

    需要说明的是,假如父类是抽象类,而如果子类也不想实现父类的方法,只要子类也是抽象类即可,这样以来,实现的代码就交给子类的下一代(个)子类来实现

    判断继承关系:

    子类 is (a) 父类;

    转换,子类 as 父类。(这个方法转换成功,返回父类对象;转换失败,返回null)

    继承的好处:

    1.代码重用;

    2.继承就是为了实现多态而准备的,多态就是一个类的多种状态(说的很模糊);这里提到一个概念,叫“里氏替换原则”,父类变量指向子类对象。多态的目的是,为了程序的可扩展性(开放封闭原则,对修改封闭,对扩展开放);下面用一个具体实例说明问题:

    需求是,要实现一个计算器,要求不论多复杂的算法,调用者只需要掉“计算”这个方法就能得到自己想要的结果,而且计算方法还会不断地扩展。这个时候考虑虚方法是不行的,因为虚方法有代码实现,所以采用抽象类是最合适不过的。抽象类的代码如下:

    public abstract class Calculator
    {
    public int Number1
    {
    get;
    set;
    }
    public int Number2
    {
    get;
    set;
    }
    //2个构造函数
    public Calculator()
    {

    }
    public Calculator(int n1,int n2)
    {
    this.Number1 = n1;
    this.Number2 = n2;
    }
    public abstract int Jisuan();
    }

    再定义一个类库,里面的类来实现上面这个类即可(如果上面的类在另外一个类库中,注意引用)。举例:加法

    public class AddFa : Calculator
    {
    public AddFa(int n1,int n2):base(n1,n2)
    {

    }
    public override int Jisuan()
    {
    return Number1 + Number2;
    }
    }

    这个时候,用一个控制台来测试上面的加法类:

    static void Main(string[] args)
    {
    Console.WriteLine("请输入第一个数:");
    int number1 = int.Parse(Console.ReadLine());
    Console.WriteLine("请输入操作符:");
    string op = Console.ReadLine();
    Console.WriteLine("请输入第二个数:");
    int number2 = int.Parse(Console.ReadLine());
    Calculator cal = MCop(op, number1, number2);
    int? iResult = cal.Jisuan(); //这里调用的是子类的计算方法
    if (iResult!=null)
    {
    Console.WriteLine("计算结果是:{0}",iResult.ToString());
    }
    Console.ReadKey();
    }
    /// <summary>
    /// 简单工厂设计模式(返回值是一个子类,“产品类”;Calculator是父类,“工厂类”,父类变量指向子类对象)
    /// </summary>
    /// <param name="op"></param>
    /// <param name="number1"></param>
    /// <param name="number2"></param>
    /// <returns></returns>
    static Calculator MCop(string op, int number1, int number2)
    {
    Calculator cal1 = null;
    switch (op)
    {
    case "+": cal1 = new AddFa(number1, number2); break;
    case "-": cal1 = new JianFa(number1, number2); break;
    }
    return cal1;
    }

    注意,当下面的方法MCop执行完毕后,返回的是产品类,再在主函数中调Jisuan(),就得到想要的结果(“产品”),这就是“简单工厂设计模式”。

    ============================================================================================

    Static关键字: 静态成员(静态字段、静态方法)

    1.类中静态成员不能通过类的实例对象名来访问,只能通过类名来访问。

    2.在静态函数中不能使用this,因为this代表类的对象;

    3.静态成员在整个程序中是共享的,一个地方改变了,其他用到它的地方都会发生改变;而且静态成员占用的内存资源直到程序退出才释放;而实例成员超出其作用域就会释放掉,一个实例成员发生变化,不影响其他实例。

    4.静态类中只能包含静态成员,而普通类(不含Static),既可以包含静态成员,也可以包含实例成员。

    5.静态类不能被继承,因为他是抽象的(abstract,不能实例化)也是密封的(Sealed,不能被继承).

    6.静态类有静态构造函数,其必须加Static关键字;静态构造函数是由系统来调用,而不是程序员来调用的。

    7.静态类中的静态成员不能有访问修饰符,也不能有参数(不知道谁传参数进去),默认是Private(私有的).

    8.静态类只能继承自Object类,不能实现任何接口(接口中的成员都是实例成员)。

    静态类使用不多,那么它的应用场景有:

     一般工具类(SQLHelper)、工具方法写成静态的,共有的、不变的属性也写成静态的;其余的属性考虑到内存占用情况,写成普通的(实例的)。

    ============================================================================================

    new关键字的用法:

    1.实例化,创建对象;

    2.如果在继承中,将子类的同名方法加一个new关键字,则表示隐藏父类继承过来的方法(因为没有通过override重写父类中的方法,故通过父类类型变量调用相同方法时访问的是父类自己的方法,而用子类类型变量调用则访问的是子类中的方法),简单点说,就是父类中的方法和子类中的方法不再有任何关系,跟继承不一样。

  • 相关阅读:
    可视化数据挖掘开源软件的比较分析
    大数据平台比较-CDH,HDP
    数据挖掘的一般过程
    httpclient介绍与请求方式详解
    30分钟带你了解阻塞队列所有内容,再也不怕面试官刁难你了!(上)
    Lock
    HashMap 源码解读
    类加载各阶段详解
    Java基础复习(八、注解)
    Java基础复习(六、反射)
  • 原文地址:https://www.cnblogs.com/chens2865/p/3360403.html
Copyright © 2020-2023  润新知