面向对象的基本概念:
(1)对象
对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
(2)对象的状态和行为
对象具有状态,一个对象用数据值来描述它的状态。
对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。
对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中
(3)类
具有相同或相似性质的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。
类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。
类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。
(4)类的结构
在客观世界中有若干类,这些类之间有一定的结构关系。通常有两种主要的结构关系,即一般--具体结构关系,整体--部分结构关系。
①一般——具体结构称为分类结构,也可以说是“或”关系,或者是“is a”关系。
②整体——部分结构称为组装结构,它们之间的关系是一种“与”关系,或者是“has a”关系。
OOD ( Object-Oriented Design ):面向对象设计
OOA ( Object-Oriented Analysis ):面向对象分析
OOP( Object Oriented Programming ):面向对象编程
类的九大成员:
字段( Field )
属性( Property )
方法( Method )
构造函数( Constructor )
析构函数( Destructor )
索引器( Indexer )
事件( Event )
运算符( Operator )
嵌套类(Nested class )
五种访问修饰符:
private:仅在类的内部访问
public:没有访问限制
internal:在同一个程序集内访问
protected:类和其派生类的内部访问
protectedinternal:类和其派生类的内部或者同一个程序集内访问
字段:
对象具有状态,这个状态是通过数据值来描述的
说的直白点就是一个对象有用来描述它的文字,字段就起到这个作用。比如:人这个对象,有性别、名字…用来对其进行具体的描述。
字段原则上是是私有的。为什么呢?因为每个对象所对应的数据值并不是一样的,为了更好的说明是那个对象就定义成私有的了。这里提到私有这个词就要注意上面的访问修饰符了。所以原则上定义字段用的访问修饰符就是:private
属性:
上面的字段已经是私有的了,那么在别的类中要访问对象中的字段怎么办呢?如果没有属性如果想访问的话就必须每个字段要写一个相应的方法。在没有属性语法的语言里通常的作法是使用对象方法来访问属性。或者理解为:属性是对私有字段的一个简单包装,使用属性而不是直接公开私有字段的一个好处就是在属性的获 取访问器或设置访问器里加入额外的逻辑并不会为客户端代码带来麻烦。
//字段
privatestring name;
//属性作用一:读写设置
//注释:get访问器,读操作;set访问器,写操作
public string Name
{
get{ return name; }
set{ name = value; }
}
//字段
private int age;
//属性作用二:验证输入数据的合法性和正确性
public int Age
{
get{ return age; }
set
{
//age= value;
if(value >= 0 && value <= 150)
{
age= value;
}
else throw new Exception("年龄输入不正确!");
}
}
属性作用三:隐藏细节
构造函数和析构函数:
namespace ConsoleApplication_shuxing
{
class Test_gaozaohanshu
{
//首先要明白构造函数和析构函数是什么?
//构造函数和析构函数分别管理对象的建立和释放,负责对象的诞生和死亡的过程。当一个对象诞生时,构造函数负责创建并初始化对象的内部环境,包括分配内存、创建内部对象和打开相关的外部资源,等等。而当对象死亡时,析构函数负责关闭资源、释放内部的对象和已分配的内存。
//构造函数
//构造函数是类中的一种特殊方法
//它的特殊性主要体现在如下几方面:
//构造函数的方法名和类名相同;
//构造函数没有返回类型;
//构造函数的主要作用是完成对类对象的初始化工作;
//在创建一个类的新对象时,系统会自动调用该的构造函数初始化新对象;
//注意:非必要我们可以不向一个类提供构造函数,编译器会在后台创建一个默认的构造函数。但如果提供了自定义的构造函数,编译器就不会提供默认的构造函数。
//下面这个是系统默认的构造函数,也是最简单的构造函数
public Test_gaozaohanshu()
{
}
//有参数的构造函数
public Test_gaozaohanshu(string str_Test)
{
Console.WriteLine(str_Test);
}
//在实例化的时候就赋值给str_Test在程序运行的时候就会将你输入的内容写在控制台应用程序上面
//构造函数的重载
//上面的两个构造函数已经形成了构造函数的重载
//重载
//函数名称相同
//在一个类中
//参数类表不同(包括参数的个数,数据类型)
//构造函数的访问修饰符
//public外,可以设置构造函数的修饰符为private及protected,若设置为private,则该类不能用这个构造函数来实例化;若设置为protected,则该类只能在派生类中用该构造函数实例化
}
//在构造函数中调用在这个类中的其他构造函数
public class UserModel
{
private string _userID;
private string _userName;
public UserModel(string userID)//带一个参数的构造函数
{
_userID = userID;
}
public UserModel(string userID, string userName)//带两个参数的构造函数
: this(userID)
{
_userName = userName;
}
//面的代码中带有两个参数的构造函数后添加了: this(userID)代码,这样就实现了调用带有一个参数的构造函数的方法。
//这种方法叫构造函数的初始化器,:this表示调用本类的构造函数,userID为参数,这样编译器就会调用那个和这个参数最匹配的构造函数。
//那这两个构造函数的执行顺序是怎样的?若按上面的代码,则是先执行有一个参数的构造函数,然后再执行有两个参数的构造函数。
}
//调用基类中的构造函数
public class User
{
private string _userID;
public User(string userID)
{
_userID = userID;
}
}
public class AdminUser : User
{
private string _userName;
public AdminUser(string userID, string userName)
: base(userID)
{
_userName = userName;
}
}
//方法和调用本类内构造函数的方法基本相同,只是将this换成了base。需要注意的是,子类必须有访问基类相应构造函数的权限,即基类的构造函数设置了合适的修饰符
}