码迷,mamicode.com
首页 > 其他好文 > 详细

第五章 类

时间:2014-11-28 16:01:48      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   color   使用   sp   for   on   

1 面向对象程序设计基础

如果一个软件系统是使用这4个概念来设计和实现的,就认为这个软件系统是面向对象的

1.1 对象

1.2 类

类是一组具有相同数据结构和相同操作的对象的集合

1.3 继承

继承是以现有类型定义为基础创建新类型的技术。

1.4 消息通信

对象与对象之间,通过消息进行通信。

2 类的生命周期

2.1 构造函数

对象的初始化通常由类的构造函数来完成。

a、构造函数的名称与类名相同

b、构造函数不声明返回类型

c、构造函数通常是公有的,如果声明为保护的或私有的,则该构造函数不能用于类的实例化

d、构造函数的代码中通常中只进行对象初始化工作,而不应执行其它操作

e、构造函数在创建对象时被自动调用,不能像其它方法那样显式的调用

    public class ConstructSample
    {
        public static void Main()
        {
        Person p = new Person();
        Console.WriteLine(p.m_name);
        }
    }

    public class Person
    {
        public string m_name;
        protected int m_age;
        protected bool m_gender;

        //构造函数
        public Person()
        {
            m_name = "Unknown";
            m_age = 0;
            m_gender = false;
        }
    }

带参数的构造函数(构造函数的重载)

    public class Person
    {
        public string m_name;
        protected int m_age;
        protected bool m_gender;

        //构造函数
        public Person()
        {
            m_name = "Unknown";
            m_age = 0;
            m_gender = false;
        }
        //构造函数重载
        public Person(string Name)
        {
            m_name = Name;
            m_age = 0;
            m_gender = true;
        }
    }

2.2 静态构造函数

如果使用了关键字static来定义构造函数,那么该构造函数就属于类而不是类的实例所有。

在程序第一次用到某个类时,类的静态构造函数自动被调用,而且是仅此一次。

静态构造函数通常用于对类的静态字段进行初始化

静态构造函数不使用任何访问限制修饰符。

    public class StaticConstructSample
    {
        public static void Main()
        {
            Person p1 = new Person("Mike");
            Person p2 = new Person("John");
            Person p3 = new Person("Mary");
        }
    }

    public class Person
    {
        public string m_name;
        public static int m_object=0;
        public static int m_classes = -1;

        //构造函数
        public Person(string Name)
        {
            m_name = Name;
            Console.WriteLine(m_name);
            Console.WriteLine("Object before:{0}", m_object);
            m_object++;
            Console.WriteLine("Object after:{0}", m_object);
        }
        //静态构造函数
        public Person()
        {
            Console.WriteLine("Classes before:{0}", m_classes);
            m_classes++;
            Console.WriteLine("Classes after:{0}", m_classes);
        }
    }

程序输出结果

Mike
Object before:0
Object after:1
John
Object before:1
Object after:2
Mary
Object before:2
Object after:3
请按任意键继续. . .

 

2.3 析构函数

对象使用完毕后,释放对象时就会自动调用类的析构函数

--析构函数的名称与类名相同,但在名称前面加了一个符号"~"

--析构函数不接受任何参数,也不返回任何值

--析构函数不能使用任何访问限制修饰符

--析构函数中的代码通常只进行销毁对象的工作,而不应执行其它的操作

--析构函数不能被继承,也不能被显示的调用

--如果类中没有显式的定义一个析构函数,编译时也会生成一个默认的析构函数,其执行代码为空。

--不存在静态的析构函数

3 属性

--为了实现良好的数据封装和数据隐藏,C#为类提供了属性(Property)成员。

--属性是对字段的扩展,它通过属性访问函数来控制对字段的访问。

--属性访问函数包括get访问函数和set访问函数,分别用于对字段的读取和修改。

例如Person类中可以使用Name属性来封装对私有字段name的访问

public class Person
{
    //字段
    private string name;
    //属性
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name=value;
        }
    }
}

public static void Main()
{
    person p1=new Person();
    p1.Name="Mike";//set
    Console.WriteLine(p1.Name);//get
}    

--定义属性时可以只声明一个访问函数。如果只有get,则表明属性的值不能为修改;如果只有set,则表明属性的值只能写入。

--和方法一样,属性可以声明为静态的,也可以使用各种访问限制修饰符

--属性可以作为特殊的方法来使用,而不必和字段一一对应

public class Person
{
    private DateTime birthday;

    public int Age
    {
        get
        {
            return DataTime.Now.Year-birthday.year;
        }
    }
}

4 索引函数

--索引函数对属性做了进一步的扩展,它能够以数组的方式来控制对多个变量的读写访问。

--和属性一样,索引函数可以被看作是get访问函数和set访问函数的组合,不同之处在于:

  --索引函数以this关键字加数组形式的下标进行定义,并通过数组形式的下标进行访问;

  --索引函数的get和set带用参数(一般为整型或字符串类型)

  --索引函数不能是静态的

  --和属性类似,索引函数的get和set访问函数中可以增加控制代码

下面的代码示例了一个Per    public class PersonTable

    {
        private Person[] m_list;

        public int Length
        {
            get
            {
                return m_list.Length;
            }
        }

        //索引函数
        public Person this[int index]
        {
            get
            {
         if(index>=0 && index <Length)   
return m_list[index];
         else
            return null;
}
set {
         if(index>=0 && index <Length)
   m_list[index]
= value;
         else
           throw new IndexOutOfRangeException(); } } }

这样对类的使用和数组的使用就非常类似了

PersonTable pt = new PersonTable(3);
pt[1]=new Person("Mike");
...
...

索引函数的访问对象不一定要是连续的数据,也可以是多个离散的字段。例如

    public class IndexerSample
    {
        static void Main()
        {
            Person p1 = new Person("李四");
            p1["BusinessPhone"] = "010888888";
            p1["BusinessFax"] = "0108888888";
            p1["MobilePhone"]="13988888888";
            p1.Output();
        }
    }

    public class Person
    {
        private string m_name;
        private string m_busiPhone;
        private string m_busiFax;
        private string m_homePhone;
        private string m_mobilePhone;

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

        //索引函数
        public string this[string Stype]
        {
            get
            {
                string type=Stype.ToUpper();
                switch (type)
                {
                    case "BUSINESSPHONE":
                        return m_busiPhone;
                    case "BUSINESSFAX":
                        return m_busiFax;
                    case "HOMEPHONE":
                        return m_homePhone;
                    case "MOBILEPHONE":
                        return m_mobilePhone;
                    default:
                        return null;
                }
            }
            set
            {
                string type=Stype.ToUpper();
                switch (type)
                {
                    case "BUSINESSPHONE":
                        m_busiPhone = value;
                        break;
                    case "BUSINESSFAX":
                        m_busiFax = value;
                        break;
                    case "HOMEPHONE":
                        m_homePhone = value;
                        break;
                    case "MOBILEPHONE":
                        m_mobilePhone = value;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }

        //构造函数
        public Person()
        {
        }

        public Person(string sName)
        {
            m_name = sName;
        }

        //方法
        public void Output()
        {
            Console.WriteLine(m_name);
            Console.WriteLine("商务电话:{0}", m_busiPhone);
            Console.WriteLine("商务传真:{0}", m_busiFax);
            Console.WriteLine("家庭电话:{0}", m_homePhone);
            Console.WriteLine("移动电话:{0}", m_mobilePhone);
        }
    }

 

5 事件

通过事件(Event),对象可以对发生的情况做出反映。

在C#的事件处理模型中,某个事件发生后,对象通过该事件的代表(delegate)调用适当的事件处理代码,此时代表充当了产生事件的对象与处理事件的方法之间的“中间人”。

System程序集中定义了一个EventArgs的类,用来封装事件中所包含的数据:此外还定义了一个名为EventHandler的delegate对象,用来作为所有事件的代表,其原型为:

public delegate void EventHandler(object sender,EventArgs e)

其中的参数sender表示发生事件的对象,而e表示事件中包含的数据。

C#中的事件也是一种特殊的方法,它包含一对内部函数add和remove,add函数将代表附加到事件上,而remove函数将移除已附加到事件上的代表。

    public class EventSample
    {
        static void Main()
        {
            Person p1 = new Person("李四");
            p1.Name = "李明";
            Console.WriteLine("当前姓名为:{0}", p1.Name);
        }
    }

    public class Person
    {
        //字段
        private string m_name;
        private string m_busiPhone;
        private string m_busiFax;
        private string m_homePhone;
        private string m_mobilePhone;

        //属性
        public string Name
        {
            get
            {
                return m_name;
            }
            set
            {
                if(m_name!=value)
                {
                    OnNameChange(this, new EventArgs());
                    m_name = value;
                }
            }
        }

        //代表
        internal EventHandler eh;

        //索引函数
        public string this[string Stype]
        {
            get
            {
                string type=Stype.ToUpper();
                switch (type)
                {
                    case "BUSINESSPHONE":
                        return m_busiPhone;
                    case "BUSINESSFAX":
                        return m_busiFax;
                    case "HOMEPHONE":
                        return m_homePhone;
                    case "MOBILEPHONE":
                        return m_mobilePhone;
                    default:
                        return null;
                }
            }
            set
            {
                string type=Stype.ToUpper();
                switch (type)
                {
                    case "BUSINESSPHONE":
                        m_busiPhone = value;
                        break;
                    case "BUSINESSFAX":
                        m_busiFax = value;
                        break;
                    case "HOMEPHONE":
                        m_homePhone = value;
                        break;
                    case "MOBILEPHONE":
                        m_mobilePhone = value;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }

        //构造函数
        public Person()
        {
        }

        public Person(string sName)
        {
            m_name = sName;
        }

        //方法
        public void Output()
        {
            Console.WriteLine(m_name);
            Console.WriteLine("商务电话:{0}", m_busiPhone);
            Console.WriteLine("商务传真:{0}", m_busiFax);
            Console.WriteLine("家庭电话:{0}", m_homePhone);
            Console.WriteLine("移动电话:{0}", m_mobilePhone);
        }

        //事件
        public event EventHandler NameChange
        {
            add
            {
                eh += (EventHandler)Delegate.Combine(eh, value);
            }
            remove
            {
                eh -= (EventHandler)Delegate.Combine(eh, value);
            }
        }

        //事件处理方法
        protected void OnNameChange(object sender, EventArgs e)
        {
            Console.WriteLine("人员姓名:{0},已经被修改", m_name);
        }
    }

 

第五章 类

标签:style   blog   io   ar   color   使用   sp   for   on   

原文地址:http://www.cnblogs.com/boywg/p/4128465.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!