C#中的面向对象编程
所有的面向对象语言都具有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#中的面向对象编程的更多相关文章
- 深入理解javascript中实现面向对象编程方法
介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是 ...
- python中的面向对象编程
在python中几乎可以完成C++里所有面向对象编程的元素. 继承:python支持多继承: class Derived(base1, base2, base3): pass 多态:python中的所 ...
- Python 第六篇(中):面向对象编程中级篇
面向对象编程中级篇: 编程思想概述: 面向过程:根据业务逻辑从上到下写垒代码 #最low,淘汰 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 #混口饭吃 def add(ho ...
- lua中的面向对象编程
简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 上述代码会输出tb1 ~= tb2.说明两个具有相同值得对象是两个不同的对象,同时在Lua中table是引用类型的 ...
- 深入解读 Js 中的面向对象编程
前言:今天看了一篇文章觉得很不错,所以给大家分享一下,也许很多人都看过面向对象编程甚至写过这样博客,觉得面向对象编程就那样,没啥好说的,那可能是因为你对这方面知识已经了解,可以选择性跳过.那如果有更通 ...
- 洗礼灵魂,修炼python(41)--巩固篇—从游戏《绝地求生-大逃杀》中回顾面向对象编程
声明:本篇文章仅仅以游戏<绝地求生>作为一个参考话题来介绍面向对象编程,只是作为学术引用,其制作的非常简易的程序也不会作为商业用途,与蓝洞公司无关. <绝地求生>最近很火,笼络 ...
- JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)
面向对象编程: 面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求 面向过程编程: 按照我们分析好的步骤,按步 ...
- Python 中的面向对象编程
面向对象编程(Object-oriented programming, OOP)是一种基于对象概念的编程范式,可包含属性(attribute)形式的数据以及方法(method)形式的代码.另一种对 O ...
- Lua中的面向对象编程详解
简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 复制代码代码如下: local tb1 = {a = 1, b = 2}local tb2 = {a = 1, b ...
- Objective-C中的面向对象编程
1.过程式编程实例,画出Shape数组中的图形: // // main.m // hello-obj // // Created by zhouyang on 16/4/4. // Copyright ...
随机推荐
- Text Reverse
Text Reverse Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- winform代码反编译后图片等资源文件恢复解决方案
用Reflector工具反编译的winform代码,图片等资源文件不能很好的反编译成功. 这里有一个笨的解决方案.首先我们要了解图片资源当初加入到工程的几种方式,及他们所在的位置. 一般winform ...
- Bzoj 1598: [Usaco2008 Mar]牛跑步 dijkstra,堆,K短路,A*
1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 427 Solved: 246[Submit][St ...
- IIS发布站点错误
发布站点的时候出现以下错误:解决方法: 1. 设置c:windows\temp 目录访问权限 temp--> 属性-->安全-- > 添加network service --> ...
- linux下安装php的swoole扩展模块(安装后php加载不出来?)
应开发同事要求,需要安装php的扩展模块swoole.swoole是一种PHP高级Web开发框架,框架不是为了提升网站的性能,而是为了提升网站的开发效率,以最少的性能损耗,换取最大的开发效率. 假设服 ...
- Ajax页面跳转
<script type="text/javascript" > $(document).ready(function () { $(&qu ...
- 学习:Linux基础知识<一>
>>硬盘分区模式 硬盘分区模式一般如下: -- / (根目录) -- /usr (操作系统) --/home (用户信息) -- /var (默认服务器的登录文件,邮件与WW ...
- Prof UIS相关
Prof UIS 一款国外的VC++仿XP系统风格的免费界面库控件,含有近20个应用实例,每一个都可以顺利编译,用它生成的菜单类似OFFICE菜单一样,比起传统的窗体视觉舒服多了,VC编程的朋友对照文 ...
- 【转】android多分辨率适配
前一阶段开发android项目,由于客户要求进行多分辨率适配,能够支持国内主流的分辨率手机.因此经过了几次开发走了很多弯路,目前刚刚领略了android多分辨率适配的一些方法. 先介绍一下所走的弯路, ...
- 草稿-Hyper-V
Hyper-V Over SMB3.0 为Hyper-v宿主机和故障转移群集做防病毒排除 微软SMB 3.0文件共享协议新特性介绍