C# 第三章 面向对象

3.1类 字段 方法

现实中的实物抽象为类

类最基本的要素是

字段:变量

方法:函数

 

构造方法(constructor)

构造方法的主要作用是完成对象的初始化工作

(1)构造方法的方法名与类名相同

(2)构造方法没有返回类型,也不能写void

 

默认(default)构造方法

如果用户没有定义任何构造方法

系统会默认一个构造方法

 

对象的创建

构造方法不能显示地直接调用,而是用new来调用

 

对象的使用

析构方法

由于C#自动进行对象的释放,所以用户一般不定义析构方法

 

方法的重载

方法的签名:方法名及参数个数及类型构成(参数名不算)

 

使用this

this指这个对象本身,常用于:

(1)访问这个对象的字段及方法

(2)区分字段与局部变量

(3)用于构造方法调用另一个构造方法,注意其位置

 

应用示例:银行系统

系统中有几类对象?Account,Bank,ATM

每个类中有什么字段、什么方法?

可在VS中,添加“类关系图”

//-------------------------------使用这些类-------------------------

public class BankDemo {

public static void Main(string [] args)

{

Bank bank = new Bank();

bank.OpenAccount("2222","2222", 20);

bank.OpenAccount("3333","3333", 50);

ATM atm = new ATM(bank);

for( int i=0; i<5; i++)

{

atm.Transaction();

}

}

}

//--------------账号类--------------------

public class Account {

double money; //decimal money;

 string id;

string pwd;

//string name;

public Account( string id, string pwd,double money )

{

//if( money < 0 ) throw newException("....");

this.id = id;

this.pwd = pwd;

this.money = money;

}

public double getMoney()

{

return money;

}

public void setMoney(double val)

{

this.money = val;

}

public string getId()

{

return id;

}

public void setId(string id)

{

this.id = id;

}

public string getpwd()

{

return pwd;

}

public void setPwd(string pwd)

{

this.pwd = pwd;

}

public bool SaveMoney( double money)

{

 if(money < 0 ) return false; //卫语句

this.money += money;

return true;

}

public bool WithdrawMoney( double money)

{

if( this.money >= money )

{

this.money -= money;

return true;

}

return false;

}

public bool IsMatch( string id, string pwd)

{

return id==this.id &&pwd==this.pwd;

}

}

//--------------------银行类----------------

using System;

using System.Collections;

using System.Collections.Generic;

public class Bank {

List<Account> accounts = newList<Account>();

public Account OpenAccount(string id,string pwd,

double money)

{

Account account = new Account(id, pwd,money);

accounts.Add( account );

return account;

}

public bool CloseAccount( Account account)

{

int idx = accounts.IndexOf(account);

if( idx<0 )return false;

accounts.Remove(account);

return true;

}

public Account FindAccount(string id,string pwd)

{

foreach(Account account in accounts)

{

if( account.IsMatch(id, pwd))

{

return account;

}

}

return null;

}

}

//---------------ATM---------

using System;

using System.Collections;

public class ATM {

Bank bank;

public ATM( Bank bank)

{

this.bank = bank;

}

public void Transaction()

{

Show("please insert your card");

string id = GetInput();

Show("please enter yourpassword");

 string pwd = GetInput();

Account account = bank.FindAccount(id,pwd);

if( account == null)

{

Show("card invalid or password notcorrent");

return;

}

Show("1: display; 2: save; 3:withdraw");

string op = GetInput();

if (op == "1")

{

Show( "balance: " +account.getMoney() );

}

else if( op=="2")

{

Show("save money");

string smoney = GetInput();

double money = double.Parse(smoney);

bool ok = account.SaveMoney(money);

if( ok ) Show("ok");

else Show("eeer");

Show("balance: " +account.getMoney());

}

else if( op=="3" )

{

Show("withdraw money");

string smoney = GetInput();

double money = double.Parse(smoney);

bool ok = account.WithdrawMoney(money);

if( ok ) Show("ok");

else Show("eeer");

Show("balance: " +account.getMoney());

}

}

 public void Show(string msg)

{

Console.WriteLine(msg);

}

public string GetInput()

{

return Console.ReadLine();// 输入字符

 

3.2属性 索引

使用属性、索引

使用属性button1.Text

使用属性 string s=”abcd”

使用索引 string s=”abcd”

 

属性(property)的书写

private string_name;

public string Name

{

         get{

                   return_name;

}

set

{

_name=value;

}

}

 

在C#3.0以上版中可简写为

public string Name{set ;get;}

 

对属性进行访问

Person p=new Person();

p.Name=”Li ming”;

Console.WriteLine(p.Name);

编译器产生的方法是:

void set_Name(string value);

string get_Name();

 

属性与字段的比较

由于属性实际上是方法

所以属性可以具有优点

可以只读或只写:只有get或set

可以进行有效性检查:if…

可以使计算得到的数据

可以定义抽象属性

 

索引器(Indexer)

修饰符类型名 this[参数列表]

{

set{};get{};

}

 

使用索引

对象名参数[]

 

3.3类的继承

继承

子类父类

C#中采用单继承

所有的类都是通过直接或间接地继承

object即(System.Object)得到的。

 

子类自动地从父类那里继承所有的

字段、方法、属性索引器等成员作为自己的成员。

除了继承父类的成员外,子类还可以

添加新的成员

隐藏或修改父类的成员

 

方法的继承、添加

方法的继承(自动)

方法的添加(多定义一些方法)

 

与父类同名的方法

一是定义同名、但参数列表与父类不同的方法,这成为对父类方法的重载

二是定义同名且参数列表也与父类相同的方法,这称为新增加一种方法,用new表示

三是定义同名且参数列表也与父类相同的方法,而且父类的方法用来abstract或virtual进行修饰,子类的同名方法用了override进行了修饰,这称为虚方法的覆盖(Overriding)

使用base

父类与子类的转换

 

as运算符

如果不能转换,则值为null

Student s3 =p1 as student;

 

与强制类型转换的差别

as只能针对引用型变量

如果不能转换,as运算不会引起异常,只是值为null

 

is运算符

if(p is Person)

判断一个对象是不能某个类(及其子类)的实例

 

3.4修饰符

访问控制符

 

static

static的字段、方法、属性是属于整个类的

static方法中,不能访问实例变量

调用static方法时,直接用类名访问

static变量可以用来表示“全局变量”

在C#2.0,类名也可以用static来修饰

 

static构造方法

static构造方法只会调用一次,但其调用时间是不确定的

 

const及readonly

const相当于静态常量

readonly相当于不可改变量,只能赋一次值

如String.Empty

在构造方法中赋值,或者在声明时就赋值

const只能用于基本类型及string

readonly只能修饰字段,而const还可以修饰局部变量

 

sealed及abstract

sealed类,不可继承(有利于编译优化)

如String Console Math Convert Graphics Font

abstract类,不可实例化(new)

如Array,RandomNumberGenerator

abstract的方法体,不用{},用

abstract 类型 方法名(参数列表)

abstract 类型 属性名{get;set;}

 

3.5接口(interface)

接口实际上是一个约定

如:ICloneable。IComparable

接口是抽象成员的集合

ICloneable含有方法clone()

IComparable含有方法compare()

接口是一个引用类型,比抽象类更抽象

作用

帮组实现多重继承

实现不相关类的相同行为

不需要考虑这些类之间的层次关系

通过接口可以了解对象的交互界面,而不需了解对象所对应的类

public sealed class String:IComparable,ICloneable,IConvertible,IEnumerable

 

定义一个接口

实现接口

 

显示接口成员实现

在实现多个接口,如果不同的接口有同名的方法

为了消除奇异,需要在方法名前写接口名

调用时,只能用接口调用

 

总之

接口是一种约定

接口中有多个抽象方法

接口能实现多继承

面向接口进行编程

 

using System;

 

interface Runner 

    void run();

}

 

interface Swimmer 

    void swim();

}

 

abstract class Animal  

{  

    abstract public void eat();

}  

 

class Person : Animal , Runner, Swimmer 

{

    public void run() 

    { 

        Console.WriteLine("run"); 

    }

    public void swim()  

    {

        Console.WriteLine("swim"); 

    }

    public override void eat() 

    { 

        Console.WriteLine("eat"); 

    }

    public void speak()

    {

        Console.WriteLine("speak"); 

    }

}

 

class TestInterface

{

    static void m1(Runner r) 

    { 

        r.run(); 

    }

    static void m2(Swimmer s) 

    { 

        s.swim(); 

    }

    static void m3(Animal a) 

    {

        a.eat(); 

    }

    static void m4(Person p)

    {

        p.speak();

    }

 

    public static void Main(string [] args)

    {

        Person p = new Person();

        m1(p);

        m2(p);

        m3(p);

        m4(p);

        Runner a = new Person();

        a.run();

 

    }

}

 

 

using System;

class InterfaceExplicitImpl

{

    static void Main()

    {

        FileViewer f = new FileViewer();

        f.Test();

        ( (IWindow) f ).Close();

         

        IWindow w = new FileViewer();

        w.Close();

    }

}

 

interface IWindow

{

    void Close();

}

interface IFileHandler

{

    void Close();

}

class FileViewer : IWindow, IFileHandler

{

    void IWindow.Close ()

    {

        Console.WriteLine( "Window Closed" );

    }

    void IFileHandler.Close()

    {

        Console.WriteLine( "File Closed" );

    }

    public void Test()

    {

        ( (IWindow) this ).Close();

    }

}

 

 

结构struct

结构常用来表示比较简单的多个分量

如Point  Color  Size DateTime  Int32

可以有方法、属性等其他成员

 

using System;

 

struct Point

{

    public double x, y;

    public Point(int x, int y) {

        this.x = x;

        this.y = y;

    }

    public double R(){

        return Math.Sqrt(x*x+y*y);

    }

}

 

class Test

{

    static void Main() {

        Point[] points = new Point[100];

        for (int i = 0; i < 100; i++)

            points[i] = new Point(i, i*i);

    }

 

 

定义struct要注意

struct是值类型

实例化时,使用new,但与引用型变量的内存是不同的

值类型变量在赋值是,实行的是字段复制。

结构不能包含无参数构造方法

每个字段在定义时,不能给初始值

构造方法中,必须对每个字段进行赋值

struct是sealed的,不能被继承。

 

枚举

枚举实际上是有意义的整数

 

using System;

enum LightColor 

{

    Red,

    Yellow,

    Green

}

class TrafficLight

{

    public static void WhatInfo(LightColor color) {

        switch(color) {

            case LightColor.Red:

                Console.WriteLine(  "Stop!" );

                break;

            case LightColor.Yellow:

                Console.WriteLine(  "Warning!" );

                break;

            case LightColor.Green:

                Console.WriteLine(  "Go!" );

                break;

            default:

                break;

        }

    }

}

 

class Test

{

    static void Main()

    {

        LightColor c = LightColor.Red;

        Console.WriteLine( c.ToString() );

        TrafficLight.WhatInfo( c );

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子非愚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值