您的位置:首页 > 编程语言 > C#

学习C# 继承 封装 多态

2016-02-13 15:04 639 查看
C# 中访问修饰符:

Private:只有类本身能存取.

Protected:类和派生类可以存取.

Internal:只有同一个项目中的类可以存取.

Protected Internal:是Protected和Internal的结合.

Public:完全存取.

C# 访问修饰符中默认修饰符

1.在namespace中的类、接口默认是internal类型的,也可以显示的定义为public类型

2.在一个类里面,属性和方法默认是private的,可以显示的定义为public、private、protected、internal或protected internal等访问类型。

3.接口中的方法默认为public的访问权限

一、封装:

  封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。

封装的意义:

  封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

  封装提供了一个有效的途径来保护数据不被意外的破坏。相比我们将数据(用域来实现)在程序中定义为公用的(public)我们将它们(fields)定义为私有的(privat)在很多方面会更好。私有的数据可以用两种方式来间接的控制。第一种方法,我们使用传统的存、取方法。第二种方法我们用属性(property)。

  使用属性不仅可以控制存取数据的合法性,同时也提供了“读写”、“只读”、“只写”灵活的操作方法。

第一种方法 用传统的读、写方法封装

让我们来看一个例子有一个类Department,为了操纵这个类中的数据(string departname)我们定义了一个读方法和一个写方法。

//通过这种方法,我们可以保护私有数据不被外部程序所破坏。使用两个不同的方法来写和读数据**
public class Department
{
private string departname; .......
// 读方法
public string GetDepartname()
{
return departname;
}
//写方法
public void SetDepartname( string a)
{
departname=a;
}
}
//主函数  我们不能直接访问类Department的实例d中的私有数据(string departname),我们只能通过读和写的方法来访问。
public static int Main(string[] args)
{
Department d = new Department();
d.SetDepartname("ELECTRONICS");
Console.WriteLine("The Department is :"+d.GetDepartname()); return 0;
}


第二种方法 用属性来实现封装

属性是c#引入的一种语言成分,只有很少的语言支持属性。通过对属性的读和写来保护类中的域。第一种方法体身也是一种好的方式,但用属性来实现封装会更方便。 现在我们来看一个例子:

//属性具有两种操作get和set。Get用来返回属性域的值。Set通过value这个变量来给属性域赋值。
public class Department
{
private string departname;
public string Departname
{
get { return departname; }
set { departname=value; }
}
}
public class Departmentmain
{
public static int Main(string[] args)
{
Department d= new Department();
d.departname="Communication";
Console.WriteLine("The Department is :{0}",d.Departname); return 0;
}
}


下面的例子是如何来实现一个只读的属性。类ReadDepartment拥有一个Departname属性只实现了get操作。它省略了写操作。这个特别的类拥有一个构造器,用来接受一个字符串变量。类ReadDepartmain中的Main方法创建了一个新的对象d。对像d的实例使用了类ReadDepartment带有一个字符串参数的构造器。因为上面的属性是只读的,所以我们不给给域departname赋值并且我们只侧读取此域中的值。当然属性也可以是只写的(write-only),这只需属性只具有一个get操作

//属性可以设为只读的(read-only),下面介绍只读属性只具有一个set操作。
using system;
public class ReadDepartment
{
private string departname;
public ReadDepartment(string avalue)
{ departname=avalue; }
public string Departname
{
get { return departname; }
}
}
public class ReadDepartmain
{
public static int Main(string[] args)
{
ReadDepartment d= new ReadDepartment("COMPUTERSCIENCE");
Console.WriteLine("The Department is: {0}",d.Departname); return 0;
}
}


第三种 封装既可以对类中的字段进行封装 数组 list数据进行封装

public class Xdagency
{
public string Xdtype { get; set; }
public List<XdDetail> Details { get; set; }  //list 泛型数据
}
public class XdDetail
{
public int Month { get; set; }
public int Count{get;set;}
}
public class LoanQueryModel
{
public int code { get; set; }
public string codedesription
{ get
{
switch (code)
{
case 1:
return "请求数据成功";
default:
return "";
}
}
}
public Message[] Message { get; set; }  //数组数据的封装
}
public class Message
{
public string type { get; set; }
public string money { get; set; }
public int c_time { get; set; }
public string use_company { get; set; }
}


二.继承:继承主要实现重用代码,节省开发时间

1.C#中的继承符合下列规则:

1.继承是可传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中的成员。Object类作为所有类的基类。

2.派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。

3.构造函数和析构函数不能被继承。除此之外的其它成员,不论对它们定义了怎样的访问方式,都能被继承。基类中成员的访问方式只能决定派生类能否访问它们。

4.派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但这并不因为这派生类删除了这些成员,只是不能再访问这些成员。

5.类可以定义虚文法、虚属性以及虚索引指示器,它的派生类能够重载这些成员,从而实现类可以展示出多态性。

2.关键字

1.重载:继承中的重载和类内的成员方法的重载是一样的,只要在子类中新建了和父类中同名的但参数列表不同的成员方法就重载了父类的成员方法,但前题是要能继承改成员方法。

2. 重写:是在子类中重新改写从父类中继承过来的某个方法,用新的方法代替原有的方法,这里要用关键字virtual override。

3.隐藏:也是在子类中重新改写从父类中继承过来的某个方法,但不父类的方法替换掉,而是隐藏起来,要用关键字new。

4.base:可以调用父类的成员方法,除了构造函数和析构函数,派生类将隐式的继承了直接基类的所有成员。也可以显示的调用父类的构造函数来构造子类的成员数据。

5.this :引用类当前的实例,还用于将对象传递到属于其他类的方法 。

3.下面给出具体的代码说明如何实现的

class A
{
public void Fun1(int i) { }
public virtual void Fun3() { }
}
class B : A
{
public void Fun1(string i)
{  //对从A类继承过来的方法进行重构     }
public new void Fun2()
{  //隐藏了从A类继承过来的方法,可以通过类型的转换从而调用被隐藏的方法     }
public override void Fun3()
{ //重写了从A类继承过来的方法,无法在调用这个方法,对于要重写的方法在父类中必须使用virtual
}
}


base 关键字

using System;
public class Person
{
protected string ssn = "444-55-6666";
protected string name = "John L. Malgraine";
public virtual void GetInfo()
{
Console.WriteLine("Name: {0}", name);
Console.WriteLine("SSN: {0}", ssn);
}
}
class Employee : Person
{
public string id = "ABC567EFG";
public override void GetInfo()
{
base.GetInfo();    //调用父类的GetInfo()方法
Console.WriteLine("Employee ID: {0}", id);
}
}
class TestClass
{
static void Main()
{
Employee E = new Employee();
E.GetInfo();
}
}


base关键字显示如何指定在创建派生类实例时调用的基类构造函数

using System;
public class BaseClass
{
int num;
public BaseClass()
{
Console.WriteLine("in BaseClass()");
}
public BaseClass(int i)
{
num = i;
Console.WriteLine("in BaseClass(int i)");
}
public int GetNum()
{
return num;
}
}

public class DerivedClass : BaseClass
{
public DerivedClass() : base() **//调用父类的构造函数**
{
}
public DerivedClass(int i) : base(i) **//调用父类的构造函数**
{
}
static void Main()
{
DerivedClass md = new DerivedClass();
DerivedClass md1 = new DerivedClass(1);
}
}
//输出
in BaseClass()    in BaseClass(int i)**


this 关键字

using System;
class Employee
{
private string name;
private string alias;
private decimal salary = 3000.00m;
public Employee(string name, string alias)
{   **//引用类当前的实例**
this.name = name;
this.alias = alias;
}
public void printEmployee()
{
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this)); **//this 将对象传递到属于其他类的方法CalcTax**
}
public decimal Salary
{
get { return salary; }
}
}
class Tax
{
public static decimal CalcTax(Employee E)
{
return 0.08m * E.Salary;
}
}
class MainClass
{
static void Main()
{
Employee E1 = new Employee("John M. Trainer", "jtrainer");
E1.printEmployee();
}
}


三 .多态

多态实现
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  继承 多态 c# class