版权声明:转载请注明出处 https://blog.csdn.net/le_17_4_6/article/details/86559564
面向对象编程基础
属性及属性的修饰符
- 对类的用户而言,属性值的读写与字段域语法相同,对编译器来说,属性值的读写是通过类中封装的特别方法get和set访问器实现的
- 属性修饰符和方法修饰符相同,包括new、static、virtual、override等
- get访问器的返回类型与属性类型相同
- set访问器没有返回值,但它有一个隐式的值参数,名称为value,value的类型和属性类型相同
- 访问器可以有自己的可访问性
- 访问器的可访问性不能高于它所属的属性
- 属性不直接对应存储位置,故不能把它当作变量使用,不能把属性作为ref或out参数传递
- 在静态属性的访问器中只能访问静态数据,不能引用this
using System;
using System.Collections.Generic;
using System.Text;
namespace PropertyExp
{
class User
{
private string m_name;
private string m_sex;
private DateTime m_birthday;
public string Name
{
get
{
return m_name;
}
set
{
m_name = value;
}
}
public string Sex //读写属性
{
get
{
return m_sex;
}
set
{
if (value == "男" || value == "女")
{
m_sex = value;
}
else
{
Console.WriteLine("性别只能为男或女");
}
}
}
public DateTime Birthday //仅写属性
{
set
{
if (value < Convert.ToDateTime("1909-1-1") || value.Year > DateTime.Now.Year - 3)
Console.WriteLine("用户的年龄非法");
else
m_birthday = value;
}
}
public int Age //仅读属性
{
get
{
return DateTime.Now.Year - m_birthday.Year;
}
}
}
class Program
{
static void Main(string[] args)
{
User a=new User();
a.Name = "林芳";
a.Sex = "女";
a.Birthday = Convert.ToDateTime("1984-7-24");
Console.WriteLine("姓名:{0},性别:{1},年龄:
{2}",a.Name,a.Sex,a.Age);
Console.ReadKey();
}
}
}
属性与字段的区别和联系
- 均可以访问对象中包含的数据
- 属性不能直接访问数据
- 属性可以限制数值的取值范围
- 属性可设置为仅读、仅写、可读写
- 属性可以象方法一样使用virtual、abstract、override、new、static等修饰符,而这些修饰符不能用于字段
抽象属性
using System;
abstract class A
{
protected int x;
public abstract int X
{
get;
set;
}
}
class B : A
{
public B(int a)
{
x = a;
}
public override int X //子类需要重载覆盖该属性的get和set
{
get
{
Console.WriteLine("in class B property X get block");
return x;
}
set
{
Console.WriteLine("in class B property X set block");
x = value;
}
}
}
class Test
{
static void Main()
{
A a= new B(3);
Console.WriteLine("{0}", a.X);
a.X = 30;
Console.WriteLine("{0}",a.X);
Console.ReadLine();
}
}
类的修饰符
访问修饰符
public, protected, private, internal, protected internal
其中protected, private, protected internal仅可用于嵌套类
internal仅仅能支持项目下程序集的其他文件访问,而protexted可以通过子类使得可以实现跨程序集的访问。
-
访问权限范围:
-
其他修饰符
abstract
抽象类,含有抽象成员,因此不能被实例化,只能用作基类
sealed
密封类,不能从该类派生出其他类
修饰符的无效组合
集合与foreach循环
- NET提供实现集合的接口,包括IEnumerable, ICollection, IList,IDictionary,
IDictionaryEnumerator, IComparer 等,只需继承实现集合接口 - 也可以直接使用.NET已经定义的集合类,包括Array, ArrayList, Queue, Stack, BitArray, Hashtable等
自定义集合:
using System;
using System.Collections;
namespace CustomCollection
{
//定义集合中的元素所属的类
class MyClass
{
public string Name;
public int Age;
public MyClass(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
//实现IEnumerator IEnumerable接口
//Current MoveNext Reset GetEnumerator
public class Iterator : IEnumerator, IEnumerable
{
private MyClass[] ClassArray;
int Cnt;
public Iterator()
{
ClassArray = new MyClass[4];
ClassArray[0] = new MyClass("Kith", 23);
ClassArray[1] = new MyClass("Smith", 30);
ClassArray[2] = new MyClass("Geo", 19);
ClassArray[3] = new MyClass("Greg", 14);
Cnt = -1;
}
//实现IEnumerator的Reset()方法
public void Reset()
{
Cnt = -1;
}
//实现IEnumerator的MoveNext()方法
public bool MoveNext()
{
return (++Cnt < ClassArray.Length);
}
//实现IEnumerator的Current属性
public object Current
{
get
{
return ClassArray[Cnt];
}
}
//实现IEnumerable的GetEnumerator()方法
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
static void Main()
{
Iterator It = new Iterator();
foreach (MyClass mc in It)
{
/*foreach循环隐藏调用IEnumerable的
GetEnumerator方法得到Iterator,并将集合指向-1的位置
foreach循环反复调用MoveNext方法移动集合,使用Current获取集合当前元素*/
Console.WriteLine("Name: " + mc.Name);
Console.WriteLine("Age: {0}", mc.Age);
}
}
}
}