面向对象的三大特性
1.封装性
将具有相同特征的一类事物高度概括扩出来
使用不同的访问权限修饰符,将类中的成员进行分配,达到更安全的效果
访问权限修饰符:如果没有在变量或者函数定义时写明是什么时候访问,那么默认是private权限
public 公有的,修饰的成员变量可以在任意其他地方进行访问,不受任何访问限制
private 私有的,修饰的成员只能在自己类内部访问,无法在外部调用
protected 受保护类型
internal 程序集公有类型
2.继承 (:)
将父类所有成员给到子类,提高代码的复用性
- 继承的定义
- 访问修饰符
- 构造函数
- sealed关键字
- this()和 base()
namespace 继承
{
class Program
{
static void Main(string[] args)
{
Player player = new Player();
}
//继承:程序中的继承就是把上一个类中的所有成员全部给下一个类
//被继承的类称为父类(基类),继承出来的类称为子类(派生类)
//继承的好处:提高代码复用性(偷懒少写代码)
//c#中禁止多重继承,只允许单继承
//访问权限修饰符
//1.public:公共的
//2.private:私有的,在子类无法访问,但是是被继承下去的
//3.protected: 受保护的,只能在自己类或者子类中获取到,在其他类中获取不到
//在继承关系中有不会被继承的东西:构造函数、析构函数
//构造函数
//1、如果一个类拥有父类的话,那么调用子类的构造函数前,会先调用父类的构造函数
//2、如果没有指定调用父类中的某一个构造函数的话,会默认调用父类中的无参构造函数
//3、如果子类想要指定调用父类中的哪一个构造函数时,可以使用:base()的形式指定
//在实例化子类对象的时候,构造函数的调用顺序是:子类静态-父类静态-父类构造-子类的构造
//sealed关键字:加在类的定义前,用于把这个类变成密封类
//密封类:无法被继承的一种类
//静态类:只能包含静态类,无法实例对象,无法派生出子类
class Actor
{
public string name;
protected int attack;
private int def;
public int hp;
static Actor()
{
Console.WriteLine("这是父类的静态构造");
}
//actor类有两个构造函数,一个是无参的,只将name赋值为张三,另一个有参,将name赋值为张三
//其他三个字段以参数为准
public Actor()
{
name = "张三";
}
public Actor(string name)
{
this.name = name;
}
//使用:this()的形式,可以让这个构造函数调用前先调用一个自己内部其他的构造函数
//使用:base()形式,可以控制这个构造函数再被调用时使用父类的哪一个构造函数
public Actor(string name, int attact, int def, int hp): this(name)
{
this.attack = attack;
this.def = def;
this.hp = hp;
}
}
class Player : Actor
{
void test()
{
name = "张三";
attack = 10;
}
static Player()
{
Console.WriteLine("这是子类的静态构造");
}
public Player(): base("张三")
{
Console.WriteLine("这是子类的构造函数");
}
public Player(string name, int attack, int def, int hp):base(name,attack, def, hp)
{
}
}
class Monster :Player
{
static Monster()
{
Console.WriteLine("孙子的静态构造");
}
}
}
3.多态
- 多态的定义
- 虚函数 virtual 虚函数
- override:方法重写
namespace 多态
{
class Program
{
static void Main(string[] args)
{
Animal[] animals = new Animal[3];
animals[0] = new Cat();
animals[1] = new Dog();
}
}
class Animal
{
//多态:不同的事物,做相同的事情时表现出不同的状态
//大多数情况下,多态和行为相关,且必须存在有继承关系
//
//virtual: 将函数变为虚函数
//虚函数:父类和子类中如果存在同名且函数的签名相同(返回值+参数列表)相同函数,如果在调用父类对象时
//想要直接使用到子类中的对应的函数,需要将父类中的函数写成虚函数
public virtual void Shout()
{
Console.WriteLine("动物叫");
}
}
class Cat : Animal
{
//override:重写
//如果父类中存在有虚函数,那么子类可以重写这个方法
//如果父类中存在虚函数,但子类中没有使用override关键字进行重写,实际上隐藏了一个关键字new(隐藏)
//1.virtual和override关键字不能和static关键字连用
//2.virtual关键字不能和override关键字一起使用
//3.override修饰的函数本身也是一个虚函数
public override void Shout()
{
Console.WriteLine("苗");
}
}
class Dog : Animal
{
public void Shout ()
{
Console.WriteLine("汪");
}
}
}
注意:
使用父类类型存储的子类对象,只能调用到属于父类的那一部分;使用接口类型存储的子类对象,只能使用接口 中有的成员;使用子类本身存储子类的对象,可以调用到所有的成员