构造方法
构造方法的定义使用
-
构造方法必须和类重名;
-
构造方法没有返回值,但可以有参数;
-
构造方法可以有多个重载;
-
不带参数的构造方法称为默认构造;
class Person
{
public string name;
public int age;
//人为的写默认构造,没有返回值,并且不加void
//方法名要和类型相同
public Person()
{
name = "战三";
age = 20;
}
//构造方法的重载,次种构造方法称为带参构造方法
public Person(string name)
{
//在带参的构造方法里面,如果人为的部分字段
//赋了初始值,其他没有赋值的字段使用默认值
this.name = name;
}
public Person (string name,int age)
{
this.name = name;
this.age = age;
}
public Person (int age)
{
this.age = age;
}
}
===========================================================
//Person()称为构造方法,构造方法名和类型相同
//当类里面没有任何构造方法时,在创建对象的时候,系统会自动生成一个不带参的构造方法用来创建对象
//构造方法只有在new对象的时候被调用一次,其他任何地方均不能人为的调用,构造方法的作用就是用来给对象的字段赋初始值,故不带参的构造方法又称为默认构造
Person p = new Person("as",2);
Console.WriteLine(p.name);
Console.WriteLine(p.age);
//如果类里面只有带参构造方法,创建对象的时候要想使用默认构造,
//必须在类的里面 ,显示吧默认构造写出来
Person p2 = new Person();
面向对象程序设计
面向过程
比如我们用面向过程的方式买一台电脑
买了CPU 主板 显卡 硬盘 内存条 机箱 风扇 电源 显示器 键盘 鼠标
我们首先需要把CPU先放到主板上面
在CPU上面涂上硅脂,装上风扇
插上内存条,用螺丝吧主板固定在机箱里面
安装硬盘 ,安装显卡 安装电源 进行插线
最后 插上显示器 和鼠标键盘我们的电脑就可以使用了
面向对象
比如我们用面向对象的方式买一台电脑
直接买一台整机就行,因为整机已经组装好的 直接买过来就可以用
面向对象的三大特性:封装,继承,多态
面向对象特征
封装
//封装:为了保护对象身上数据的安全性,需要对字段进行封装,
//既在类的外部,通过对象不能够直接访问到对象的字段,把字段的访问权限改成私有的
例:=======================================================================
class Book
{
public string Name { get; set; }
public double Price { get; set; }
public string Author { get; set; }
public Book (string name,double price,string author)
{
Name = name;
Price = price;
Author = author;
}
}
===================================================================
Book book = new Book("金瓶梅", 66, "武大梁");
继承
继承定义
class Student
{
//1.字段写成私有的
string name;
int age;
//通过带参构造方法给字段赋初始值
public Student (string name,int age)
{
this.Name = name;
this.Age = age;
}
//public Student()
//{
// Console.WriteLine("Student");
//}
//3.借助属性来单独修改字段的值
public string Name { get => name; set => name = value; }
public int Age { get => age; set => age = value; }
public void Study()
{
Console.WriteLine("学生学习");
}
}
//在一个类的后面加上:类,称为类的继承
//Senior称为子类(派生类),Student称为父类(基类)
class Senior : Student
{
public string number;
public Senior (string name,int age,string number):base(name,age)
{
this.number = number;
}
//如果子类有一个和父类一样的方法,称为方法的替换
//此时子类在调用该方法时,会调用子类新实现的方法,可以
//在子类的方法前面加new关键字,吧父类的方法给隐藏掉
public void Study()
{
Console.WriteLine("学生学习");
}
}
//当子类里面有默认构造,创建对象时需要调父类的默认构造
//故要确保在父类里面有默认构造,如果父类里面没有任何构造方法,
//系统会自动生成一个默认构造,如果父类里面有带参构造方法
//则需要显示吧默认构造写出来
//一个子类不能够同事继承多个父类,但是可以使用类的传递性
//继承多个父类,Junior既是Senior的子类,也是Student的子类
//Senior的父类是Student,子类是Junior,Student的子类既是
//Senior也是Junior
class Junior : Senior
{
string number;
public Junior(string name,int age,string number) : base(name,age,number)
{
Console.WriteLine("Junior");
}
}
总结
-
派生类获得基类的所有方法、字段、属性和事件。
-
继承具有传递性。
-
派生类可以赋值给基类,但是基类不能赋值给派生类。
多态
里氏转换
//Object是所有类型的基类
class Hero
{
public void Fire(EnemyBase enemy)
{
//根据里氏转换第一原则,此时所调用的方法均为父类里面的
//enemy.BeAttacked();
//下面使用里氏转换第二原则,吧父类对象转成子类对象
XiaoGuai xiaoguai = enemy as XiaoGuai;
if (xiaoguai!=null)
{
xiaoguai.BeAttacked();
}
Boss boss = enemy as Boss;
if (boss!=null)
{
boss.BeAttacked();
}
}
}
class EnemyBase
{
public int HP { get;set; }
public void BeAttacked()
{
HP -= 1;
}
}
class XiaoGuai:EnemyBase
{
}
class Boss:EnemyBase
{
public new void BeAttacked()
{
HP -= 5;
}
}
====================================================================
EnemyBase xg = new XiaoGuai();
EnemyBase b = new Boss();
xg.HP = 100;
b.HP = 1000;
Hero h = new Hero();
h.Fire(xg);
Console.WriteLine(xg.HP);
h.Fire(b);
Console.WriteLine(b.HP);
//以上的代码存在以下的问题:
//1.需要对类型进行转换
//2.如果子类过多,要写的代码也会增多,造成写代码的效率比较低,需要解决该问题,
//需要使用虚方法的多态,具体方法如下:
//1.把父类里面的方法写成虚方法
//2.在子类里面吧父类的虚方法重写
//子类对象赋值父类对象以后,子类如果重写了父类的虚方法,则调用
//子类重写后的方法,如果没有重写父虚方法,则调用父类的方法
is关键字
is用来判断一个对象是否是指定的类型,是的话返回true,否则返回false
例===========================================================
Person p = new Student();
Student s = new Student();
bool b = s is Person();
//先判断student是否是Person类型,如果是就强制转换
if (b)
{
Person per = (Person)Student;
}
//否则就不转换,如果不判断,转换不成功系统会报错
as关键字
as是转换运算符,转换成功,就转换成as后面的类型,否则返回null
例===========================================================
//进行转换,如果转换成功就是 后面的类型,如果转化不成功就是null
XiaoGuai xiaoguai = enemy as XiaoGuai;
if (xiaoguai!=null)
{
xiaoguai.BeAttacked();
}
虚方法和重写
class Hero
{
public void Fire(EnemyBase enemy)
{
enemy.BeAttacked();
}
}
class EnemyBase
{
public int HP { get;set; }
//virtual 是关键字,可以吧方法变成虚方法
public virtual void BeAttacked()
{
HP -= 1;
}
}
class Boss:EnemyBase
{
//override用来重写父类的虚方法
public override void BeAttacked()
{
HP -= 5;
}
}
========================================================
EnemyBase xg = new XiaoGuai();
EnemyBase b = new Boss();
xg.HP = 100;
b.HP = 1000;
Hero h = new Hero();
h.Fire(xg);
Console.WriteLine(xg.HP);
h.Fire(b);
Console.WriteLine(b.HP);
//就这几段代码 比刚才的里氏转换方便太多了 有木有
sealed关键字
class Hero
{
public void Fire(EnemyBase enemy)
{
enemy.BeAttacked();
}
}
class EnemyBase
{
public int HP { get;set; }
public virtual void BeAttacked()
{
HP -= 1;
}
}
class Boss:EnemyBase
{
//sealed表示密封的,放在重写的方法前面,表示该方法不饿能够再被他的子类重写
//放在类前面表示该类是密封类,密封类不能够被继承
public sealed override void BeAttacked()
{
HP -= 5;
}
}
class Jibo:Boss
{
public override void BeAttacked()//这里会报错
{
HP -= 5;
}
}
总结
- 构造方法
- 面向对象思想变成
- 封装、继承、多态