private:私有成员,在类的内部才可以访问
public:公共成员,完全公开,没有访问限制
protected:保护成员,该类内部和继承类中可以访问
internal:当前程序集内可以访问。程序集:exe\dll中
internal protected:internal和protected的并集,同一个程序集中的所有类,以及所有程序集中的子类
行为(方法)和字段(数据)的结合
含义:将字段(数据成员)和行为(代码成员)相结合的一种机制
目的:
1、控制对象状态的范围
2、加强对象自身的内联(联动)性
3、增强对象使用的安全性
封装图解
封装的基本要求:
特定边界:所有内部变化都限制在此边界内(类定义的{ })
特定访问权限:在对象外部不能访问或修改受保护的内部实现细节(private成员)
有外部接口(方法):此对象利用它与其它对象发生关联(public成员)
例如:银行的取钱方案等
namespace ConsoleApp1
{
class Hero
{
//血量
int hp;
//性别
char gender;
//状态:true:活着 false:挂了
bool state;
public Hero(int hp)
{
this.hp = hp;
this.state = true;
}
/// <summary>
/// 受到伤害
/// </summary>
/// <param name="hurt"> 被伤害的数值</param>
public void BeHurt(int hurt)
{
if (hurt < 0)
{
return;
}
this.hp = this.hp - hurt < 0 ? 0 : this.hp - hurt;
if (this.hp == 0)
{
this.state = false;
}
}
/// <summary>
/// 获取当前英雄血量值
/// </summary>
/// <returns></returns>
public int GetHp()
{
return hp;
}
public void SetGender(char gender)
{
if (gender == '男' || gender == '女')
{
this.gender = gender;
return;
}
Console.WriteLine("性别必须为男或者女!");
this.gender = '男';
}
public char GetGender()
{
return this.gender;
}
public bool GetState()
{
return this.state;
}
public void Attact()
{
if (this.state)
{
Console.WriteLine("普通攻击!");
}
else
{
Console.WriteLine("你已经阵亡,请等待复活");
}
}
}
}
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
TestHero();
}
public static void TestHero()
{
Hero h = new Hero(1800);
h.BeHurt(1000);
Console.WriteLine(h.GetHp());
h.SetGender('X');
Console.WriteLine(h.GetGender());
while (h.GetState())
{
h.Attact();
h.BeHurt(500);
}
}
}
}
上图这样的模式称为封装,类内部有联动性
举例:写一个学生类,成绩与挂科与否
namespace Student
{
class Student
{
//0-100
int score;
//false:不挂科 true:挂科
bool over;
public void SetScore(int score)
{
if (score < 0 || score > 100)
{
Console.WriteLine("成绩无效!");
return;
}
this.score = score;
//做字段了联动
over = this.score < 60;
}
public int GetScore()
{
return this.score;
}
public bool GetOver()
{
return this.over;
}
}
}
namespace Student
{
class Program
{
static void Main(string[] args)
{
TestStudent();
}
public static void TestStudent()
{
Student s = new Student();
s.SetScore(1000);
Console.WriteLine(s.GetOver() ? "挂了" : "没挂");
}
}
}
封装的安全性
举一个例子:用户的User界面
namespace User
{
class User
{
String name; //名字只能看,不能改,需要封装
int password; //应该可以改也可以拿
int key = 171816; //加密key
public string GetName()
{
return this.name;
}
public void SetPassword(int password)
{
this.password = password ^ key ;
}
public int GetPassword()
{
return this.password;
}
public User()
{
}
public User(string name, int password)
{
this.name = name;
this.SetPassword(password);
}
public bool Login(int password)
{
if (this.password == (password ^ key))
{
return true;
}
return false;
}
}
}
namespace User
{
class Program
{
static void Main(string[] args)
{
TestUser();
}
public static void TestUser()
{
Console.WriteLine("注册密码:");
User user = new User("admin", int.Parse(Console.ReadLine()));
Console.WriteLine(user.GetPassword());
Console.WriteLine("验证密码");
bool login = user.Login(int.Parse(Console.ReadLine()));
Console.WriteLine(login);
}
}
}
属性封装
属性的定义:属性代表了set和get方法