c# 继承 和 关键字:abstract,const,override,readonly,static,virtual,base,this

最近手头紧,老想去银行弄点钱,哈哈,弄个银行业务来做个小例子,边做例子,边总结业务。

1.定义存钱和取钱接口。接口命名,一般在名字前面加一个大写的I,表示接口。

注意这里,我们把namespace定义成:CSharp.Bank,也就是说在这个namespace下,都是关于银行的东西。便于我们归类而已。没其它用处。

Code
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;

namespace CSharp.Bank
{
    
interface IBank
    {
        
bool SaveMoney(decimal money);
        
bool GetMoney(decimal money);
    }
}

2. 写一个抽象(abstract)类。(完整代码,包含上面的interface)

Code
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;

namespace CSharp.Bank
{
    
interface IBank
    {
        
bool SaveMoney(decimal money);
        
bool GetMoney(decimal money);
    }

    
public abstract class CenterBank : IBank
    {

        
//银行剩余存款,自己给自己多弄点。
        private decimal _total = 9999999//好多钱啊,不愁啦。

        
#region IBank 成员

        
public bool SaveMoney(decimal money)
        {
            
//throw new NotImplementedException();

            
//存钱
            this._total += money; // 等于this._total = this._total + money;
            return true//存钱成功啦
        }

        
public bool GetMoney(decimal money)
        {
            
//throw new NotImplementedException();

            
//先判断存款是否够我取的,我们不能透支啊,经济危机来了,要节约哦。
            if (this._total >= money)
            {
                
this._total -= money;
                
return true//取钱成功
            }
            
else
            {
                
return false;//取钱失败,因为余额不足。
            }
            
        }

        
//定义一个抽象方法
        public abstract decimal GetTotal();

        
#endregion
    }
}

抽象类不能直接被实例化,用abstract来声明,如:public abstract class CenterBank

CenterBank : IBank 表示CenterBank 继承(或者说“实现”)自IBank, 用的操作是一个冒号":".其它语言,如java/php,用的是extend,比如:CenterBank extend IBank.
在c#中,一个类,可以同时继承(或叫“实现”)多个接口,比如:
CenterBank :IBank,IBank2,IBank3,IBank4 , 多个接口之间用逗号隔开。


this._total += money; -- this关键字,表示当前类的对象。

类简单理解,比如:class AA{},那么AA就是一个类,那么什么是对象呢?比如:


AA objAA1 = new AA();

AA objAA2 = new AA();

那么objAA1,objAA2就是类AA的对象,或者叫:实例。

public abstract decimal GetTotal(); 定义抽象方法,抽象方法同接口的方法,不过是用abstract关键来声明而已,抽象方法不包含具体的实现代码。

 

3.具体的类。(可以拿来用的那种)

在这里,我们为抽象类:CenterBank 增加了一个属性:Total

Code
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;

namespace CSharp.Bank
{
    
interface IBank
    {
        
bool SaveMoney(decimal money);
        
bool GetMoney(decimal money);
    }

    
public abstract class CenterBank : IBank
    {

        
//银行剩余存款,自己给自己多弄点。
        private decimal _total = 9999999//好多钱啊,不愁啦。

        
//定义一个属性。类似方法
        public decimal Total
        {
            
set { _total = value; }
            
get { return _total; }
        }

        
#region IBank 成员

        
public bool SaveMoney(decimal money)
        {
            
//throw new NotImplementedException();

            
//存钱
            this._total += money; // 等于this._total = this._total + money;
            return true//存钱成功啦
        }

        
public bool GetMoney(decimal money)
        {
            
//throw new NotImplementedException();

            
//先判断存款是否够我取的,我们不能透支啊,经济危机来了,要节约哦。
            if (this._total >= money)
            {
                
this._total -= money;
                
return true//取钱成功
            }
            
else
            {
                
return false;//取钱失败,因为余额不足。
            }
            
        }

        
//定义一个抽象方法
        public abstract decimal GetTotal();

        
#endregion
    }

    
//中国银行
    public class ChinaBank : CenterBank
    {

        
public override decimal GetTotal()
        {
            
//throw new NotImplementedException();
            return base.Total; //返回我实际的余额
        }
    }

    
public class CCB : CenterBank
    {

        
public override decimal GetTotal()
        {
            
//throw new NotImplementedException();

            
return 0//建行比较烂,就返回一个0给我。
        }
    }
}

ChinaBank继承自 CenterBank后,就必须要实现抽象方法:GetTotal(),实现方式:
public override decimal GetTotal()

override  关键字就是表示重载父类的方法。

 

return base.Total; //返回我实际的余额

base 关键字就是调用父类的方法,也就是说base是父类的对象,是对父类的引用。

 

4.有了银行,我们就要开始花钱啦。

给抽象类,增加了一个虚方法:AutoAddMoney(),新增两个类:Shop和Me

Code
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;

namespace CSharp.Bank
{
    
interface IBank
    {
        
bool SaveMoney(decimal money);
        
decimal GetMoney(decimal money);
    }

    
public abstract class CenterBank : IBank
    {

        
//银行剩余存款,自己给自己多弄点。
        private decimal _total = 0//

        
//定义一个属性。类似方法
        public decimal Total
        {
            
set { _total = value; }
            
get { return _total; }
        }

        
#region IBank 成员

        
public bool SaveMoney(decimal money)
        {
            
//throw new NotImplementedException();

            
//存钱
            this._total += money; // 等于this._total = this._total + money;
            return true//存钱成功啦
        }

        
public decimal GetMoney(decimal money)
        {
            
//throw new NotImplementedException();

            
//先判断存款是否够我取的,我们不能透支啊,经济危机来了,要节约哦。
            if (this._total >= money)
            {
                
return money;
            }
            
else
            {
                
return 0;//取钱失败,因为余额不足。
            }
            
        }

        
//定义一个抽象方法
        public abstract decimal GetTotal();

        
public virtual void AutoAddMoney()
        {
            
this._total += 500;
        }

        
#endregion
    }

    
//中国银行
    public class ChinaBank : CenterBank
    {

        
public override decimal GetTotal()
        {
            
//throw new NotImplementedException();
            return base.Total; //返回我实际的余额
        }

        
//public override void AutoAddMoney()
        
//{
        
//    base.AutoAddMoney();
        
//}
    }

    
public class CCB : CenterBank
    {

        
public override decimal GetTotal()
        {
            
//throw new NotImplementedException();

            
return 0//建行比较烂,就返回一个0给我。
        }
    }

    
//定义一个商店,卖卖车,卖卖房子.
    public class Shop
    {
        
//定义车,一辆车15万
        public const decimal Car = 150000;

        
//定义房子,一套房子50万
        public const decimal House = 500000;
    }

    
public class Me
    {
        
//定义一个变量,用来存放手里的现金
        private static decimal _money = 0;
        
        
//定义两个变量,表示是否有房有车,默认为false,表示没车没房。
        private bool _hasCar = false;
        
private bool _hasHouse = false;

        
public void Buy()
        {
            

            BuyCar();
            BuyHouse();

            Console.WriteLine(
"有车啦?");
            Console.WriteLine(_hasCar 
? "":"没有");
            Console.WriteLine(
"有房啦?");
            Console.WriteLine(_hasHouse 
? "" : "没有");
            Console.WriteLine(
"还剩几毛?");
            Console.WriteLine(GetBalance());

            
if (GetBalance() > 300000)
            {
                Console.WriteLine(
"Oh,yeah,我好有钱啊");
            }
            
else
            {
                Console.WriteLine(
"穷啊");
            }

            Console.ReadLine();
        }

        
public static void SetMoney(decimal money)
        {
            Me._money 
= money;
        }

        
//买车
        private bool BuyCar()
        {
            
if (Me._money >= Shop.Car)
            {
                _hasCar 
= true//修改_hasCar的值为true,表示我们有车啦
                Me._money -= Shop.Car; // 买了车后,我的现金就少啦。
                return true;
                
//如果_money >= _car ,方法执行到这里就退出了。表示购买成功。
            }

            
//如果_money < _car ,就返回false。表示购买不成功。
            return false;
        }

        
//买房
        private bool BuyHouse()
        {
            
if (Me._money >= Shop.House)
            {
                _hasHouse 
= true;
                Me._money 
-= Shop.House;
                
return true;
            }

            
return false;
        }

        
//获取余额
        private decimal GetBalance()
        {
            
return Me._money;
        }
    }
}

虚方法定义方式:

public virtual void AutoAddMoney()
       

使用virtual关键字。其实virtrual 方法跟普通方法没啥区别。但是官方的解释是
virtrual的行为类似abstract方法,不过virtrual方法有自己的代码实现,而abstract方法没有自己的实现。
所以,我觉得还不如拿
virtrual方法直接和普通方法比较,比如和上面的private decimal GetBalance()比较。在用法上,这两个没啥区别,一样用。

 

const和readonly。 总体来讲,这两个关键字都是限制字段只能读,不能写。唯一的区别就是定义const字段时,必须在声明的时候,就要赋值,如上面的例子。
而readonly字段可以在声明的时候或者构造函数的时候赋值。

static关键字 -- 上面的现金余额使用的static关键字来定义。因为我们的现金只有一个实例。没有多个实例。 看下面运行结果解释。

运行测试代码如下:

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CSharp.Bank;

namespace CSharp
{
    
class Program
    {
        
static void Main(string[] args)
        {

            
//实例化ChinaBank类。 使用new关键字。
            ChinaBank  objChinaBank = new ChinaBank();

            
//调用方法
            objChinaBank.SaveMoney(1000000);
            Console.WriteLine(objChinaBank.GetTotal());
            objChinaBank.AutoAddMoney();
            Console.WriteLine(objChinaBank.GetTotal());

            Me.SetMoney(objChinaBank.GetMoney(
999999));

            Me objMe1 
= new Me();
            objMe1.Buy();
            
            Me objMe2 
= new Me();
            objMe2.Buy();
        }
    }
}

运行结果:

 

在测试代码里面,我们定义了两个Me类的实例:

 Me objMe1 = new Me();
            objMe1.Buy();
            
            Me objMe2 
= new Me();
            objMe2.Buy();

为了是现金保持同一个实例,所以我们比如使用static字段来定义_money.

第一次运行之前,我们的取的现金是999999

第一次运行的时候,剩余金额是349999,

第二次运行的时候,初始金额就是349999了,而不是999999。可以去掉_money的static属性,然后重新测试代码。

 

最后,关键字详细解释:http://msdn.microsoft.com/zh-cn/library/x53a06bb(VS.80).aspx

posted @ 2009-01-07 15:08  无尽思绪  阅读(1657)  评论(0编辑  收藏  举报