所有的面向对象语言都具有3个基本特征,C#也是不例外的。

  • 封装---把客观事物封装成类,并将类内部的实现隐藏,以保证数据的完整性;
  • 继承---通过继承可以复用父类的对象;
  • 多态---允许将子对象赋值给扶对象的一种能力。

1、封装

封装指的是把类内部的数据隐藏起来,不让对象实例直接对其操作。在C#中,封装可以通过public private protected和internal等关键字来体现。

C#对保护内部数据状态提供了一种方式,叫做属性机制。

public class Person
{
    private string _name;
    private int _age;

public string Name
    {
        get{return _name;}
        set{_name=value;}
    }

public int Age
    {
        get{return _age;}
        set
        {
            //在属性定义中,可以根据系统的业务逻辑添加逻辑代码
            if(value<0 || value>120)
           {
               throw(new ArgumentOutOfRangeException("AgeIntProperty",value,"年龄必须在0-120之间"));
           }
          _age=value;
        }
    }
}

2、继承

在C#中,一个类可以继承另外一个已有的类,子类会获得基类除构造函数和析构函数以外的所有成员。同时静态类和密封类是不能被继承的。

C#与C++不一样,只支持单继承。

//基类

public class Animal

{

  private int _age;

  public int Age

  {

    get{return _age;}

    set

    {

        if(value<0 || value>10)
               {
                     throw(new ArgumentOutOfRangeException("AgeIntProperty",value,"年龄必须在0-10之间"));
                }
             _age=value;

    }

  }

}

//子类(马)

public class Horse:Animal

{}

//子类(羊)

public class Sheep:Animal

{}

有一点需要注意:子类并不能对父类的私有成员进行直接访问,它只可对保护成员和公有成员进行访问。

私有成员也会被子类继承,但子类不能直接访问私有成员,子类可以通过调用公有或保护方法来间接地对私有成员进行访问。

2.1 密封类

public sealed class SealedClass

{

  //在这里定义类成员

}

//密封类不能作为其他类的基类,下面代码编译时会出错

public class Test :SealedClass

{}

2.2 子类的初始化顺序

当我们初始化一个子类时,除了会调用子类的构造函数外,同时也会调用基类的构造函数。子类的初始化顺序如下:

(1)初始化类的实例字段;

(2)调用基类的构造函数,如果没有指明基类,则调用System.Object的构造函数;

(3)调用子类的构造函数。

下面就通过一个实例来说明:

//父类

public class Parent

{

  //②调用基类的构造函数

  public Parent()

  {

    Console.WriteLine("基类的构造函数被调用了");

  }

}

//子类

public class ChildA:Parent

{

  //创建一个ChildA对象时

  //①初始化它的实例字段

  private int FieldA=3;

  //③调用子类构造函数

  public ChildA()

  {

    Console.WriteLine("子类的构造函数被调用");

  }

  

  public void Print()

  {

    Console.WriteLine(FieldA);

  }

}

class Program

{

  static void Main(string[] args)

  {

    ChildA childa=new ChildA();

  }

}

3、多态

多态的定义:即相同类型的对象调用相同的方法却表现出不同行为的现象。

3.1 使用virtual和override关键字实现方法重写

只有基类成员声明为virtual或abstract时,才能被派生类重写;而如果子类想改变虚方法的实现行为,则必须使用override关键字。

public class Animal

{

  private int _age;

  public int Age

  {

    get{return _age;}

    set

    {

      if(value<0 || value>10)

      {

         throw(new ArgumentOutOfRangeException("AgeIntProperty",value,"年龄必须在0-10之间"));

      }

    }

  }

  //几乎所有动物都具有发出声音的能力

  //但是对于动物来说,每种动物发出的声音是不一样的

  public virtual void Voice()

  {

    Console.WriteLine("动物开始发出声音");

  }

}

//马(子类),子类应重写基类的方法,以实现自己特有的行为

public class Horse:Animal

{

  //通过override关键字来重写父类方法

  public override void Voice()

  {

    Console.WriteLine("马叫");

  }

}

//羊(子类)

public class Sheep:Animal

{

  //通过override关键字来重写父类方法

  public override void Voice()

  {

    Console.WriteLine("羊叫");

  }

}

class Program

{

  static void Main(string[] args)

  {

    Animal horse=new Horse();//把子类对象赋给父类变量

    horse.Voice();

    Animal horse=new Horse();//把子类对象赋给父类变量

    horse.Voice();

    Console.ReadKey();

  }

}

如果在子类中还要访问父类中虚的方法,就必须要用base关键字来完成调用。base.Voice();

对于上面那种情况,建议把Animal类设置成抽象类,采用abstract关键字来防止在代码中直接创建这样类的实例。

3.2 阻止派生类重写虚成员

public class Horse:Animal

{

  //采用sealed关键字,Horse就不能再扩展Voice方法了

  public sealed override void Voice()

  {

    //调用基类方法

    base.Voice();

    Console.WriteLine("马叫");

  }

}

3.3 使用新成员隐藏基类成员

可以在子类中采用new的关键字来隐藏父类成员

public class Horse:Animal

{

  public new void Voice()

  {

    ......

  }

}

采用这样的形式,如果要调用父类的方法,只能把对象强制转换成父类类型。

4、所有类的父类

在C#中,所有的类都派生自System.Object类,底下是Object类的一些成员:

public class Object

{

  //方法

  //构造函数

  public Object();

  //虚成员,子类可以重写这些方法

  public virtual bool Equals(object obj);

  protected virtual void Finalize();

  public virtual int GetHashCode();

  public virtual string ToString();

  //实例成员

  public Type GetType();

  public object MemberwiseClone();

  //静态成员

  public static bool Equals(object objA,object objB);

  public static bool ReferenceEquals(object objA,object objB);

}

小结:此篇文章讲的是C#在面向对象方面的一些基本知识点,如果能把这3个特性搞熟透的话,在做项目的时候,你的思路就会比较多了。

C#中的面向对象编程的更多相关文章

  1. 深入理解javascript中实现面向对象编程方法

    介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是 ...

  2. python中的面向对象编程

    在python中几乎可以完成C++里所有面向对象编程的元素. 继承:python支持多继承: class Derived(base1, base2, base3): pass 多态:python中的所 ...

  3. Python 第六篇(中):面向对象编程中级篇

    面向对象编程中级篇: 编程思想概述: 面向过程:根据业务逻辑从上到下写垒代码  #最low,淘汰 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 #混口饭吃 def add(ho ...

  4. lua中的面向对象编程

    简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 上述代码会输出tb1 ~= tb2.说明两个具有相同值得对象是两个不同的对象,同时在Lua中table是引用类型的 ...

  5. 深入解读 Js 中的面向对象编程

    前言:今天看了一篇文章觉得很不错,所以给大家分享一下,也许很多人都看过面向对象编程甚至写过这样博客,觉得面向对象编程就那样,没啥好说的,那可能是因为你对这方面知识已经了解,可以选择性跳过.那如果有更通 ...

  6. 洗礼灵魂,修炼python(41)--巩固篇—从游戏《绝地求生-大逃杀》中回顾面向对象编程

    声明:本篇文章仅仅以游戏<绝地求生>作为一个参考话题来介绍面向对象编程,只是作为学术引用,其制作的非常简易的程序也不会作为商业用途,与蓝洞公司无关. <绝地求生>最近很火,笼络 ...

  7. JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)

    面向对象编程:   面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求   面向过程编程:         按照我们分析好的步骤,按步 ...

  8. Python 中的面向对象编程

    面向对象编程(Object-oriented programming, OOP)是一种基于对象概念的编程范式,可包含属性(attribute)形式的数据以及方法(method)形式的代码.另一种对 O ...

  9. Lua中的面向对象编程详解

    简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 复制代码代码如下: local tb1 = {a = 1, b = 2}local tb2 = {a = 1, b ...

  10. Objective-C中的面向对象编程

    1.过程式编程实例,画出Shape数组中的图形: // // main.m // hello-obj // // Created by zhouyang on 16/4/4. // Copyright ...

随机推荐

  1. 提高IIS的并发量

    IIS 7.0使用的是默认配置,服务器最多只能处理5000个同时请求. 根据相关文档调整设置,可以让服务器从设置上支持10万个同时请求 . 调整IIS 7应用程序池队列长度 由原来的默认1000改为6 ...

  2. java基础(十六)集合(三)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...

  3. OpenCL memory object 之 Global memory (1)

    本文转载自:http://www.cnblogs.com/mikewolf2002/archive/2011/12/17/2291239.html 这篇日志是学习AMD OpenCL文档时候的总结. ...

  4. 筛1-n中每个数的因子(nlogn)

    void get_div() //筛因子 { ; i<maxn; i++) for(int j=i; j<maxn; j+=i) dx[j].push_back(i); }

  5. mysql 备份与还原

    http://dev.yesky.com/281/35291281.shtml 每一种逻辑错误发生的概率都极低,但是当多种可能性叠加的时候,小概率事件就 放大成很大的安全隐患,这时候备份的必要性就凸显 ...

  6. Java-String之寻根问底

    Java-String之寻根问底 引言 在java编程中,几乎每天都会跟String打交道,因此,深入理解String及其用法十分有必要.下面分三方面来详细说明下String相关的特点及用法 •Imm ...

  7. yii项目开发项目常用技巧和方法汇总

    1.使用CActiveForm类组件如何输出不带html属性的结果 eg:<?php echo $form->textField($model,'email',array('size'=& ...

  8. Shell函数参数

    在Shell中,调用函数时可以向其传递参数.在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数... 带参数的函数示例: #!/bin/bash funWit ...

  9. 在终端中创建一个简单的mysql表格

    打开终端后输入:/usr/local/MySQL/bin/mysql -u root –p 然后输入密码:***** 创建数据库:create database work; 使用当前数据库:use w ...

  10. 几种不同风格的Toast

    一般情况下,我们使用Toast默认的风格就行了,只是有些时候为了达到我们自己想要的效果需要自定义一下,包括自定义显示的位置,显示的内容以及完全自定义里面的布局,代码如下: activity: pack ...