语法:[public] class 子类类名:父类类名
我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类。
父类——子类
基类——派生类
有一个特殊的类:object,object是所有类的基类。
子类的对象可以调用父类中的成员,但是父类对象永远只能调用自己的成员。
访问修饰符——protected:受保护的,可以在当前类的内部以及该类的子类中被访问。
子类从父类那里继承了什么?首先,子类继承了父类的属性和方法
但是,父类的私有字段并没有被继承
最后,我们来思考一下,子类有没有继承父类的构造函数?
如果继承了,那么从理论上讲当你创建子类对象的时候,应该可以调用到父类的构造函数。
我们在父类中创建一个构造函数
出现了报错。
又在父类中创建了一个无参的构造函数,不再报错
这个时候,子类只能调用自己的构造函数
在子类中写一个无参的构造函数,在person类中设置断点进行调试
经过调试,发现子类执行完父类的无参构造函数之后再执行了自己的无参构造函数。
总结:
当我们创建子类对象的时候,首先会在子类的内部创建一个父类的对象,这样父类中的成员才能让子类使用。
所以说,子类并没有继承父类的构造函数。但是会默认调用父类无参数的构造函数。相当于创建了一个父类对象,让子类可以使用父类中的成员。
如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,所以才会报错。
有两种解决方法:
1.在父类中重新写一个无参数的构造函数
2.在子类中显示的调用父类的构造函数,使用关键字 :base()
继承的特性:1.单根性:一个子类只能有一个父类
2.传递性:可以一个传递一个(爷爷传父亲,父亲传儿子)
new关键字
之前我们学过new关键字的作用是,创建对象
当我们在父类和子类中使用了同样的名称命名一个方法时,发现子类对象只能调用到自己的方法,父类的无法调用。
new关键字还可以隐藏从父类那里继承的同名成员。隐藏的后果就是子类调用不到父类的成员。
面向对象继承练习
创建父类
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
private char _gender;
public char Gender
{
get { return _gender; }
set { _gender = value; }
}
public Person(string name,int age,char gender)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
}
}
子类driver
public class Driver:Person
{
private int _driveTime;
public int DriveTime
{
get { return _driveTime; }
set { _driveTime = value; }
}
public void DriverSayHello()
{
Console.WriteLine("我叫{0},我是司机,我年龄是{1},我是{2}人,我的驾龄是{3}", this.Name, this.Age, this.Gender, this.DriveTime);
}
public Driver(string name,int age,char gender,int driveTime) : base(name, age, gender)
{
this.DriveTime = driveTime;
}
}
子类programmer
public class Programmer:Person
{
private int _workYear;
public int WorkYear
{
get { return _workYear; }
set { _workYear = value; }
}
public void ProgrammerSayHello()
{
Console.WriteLine("我叫{0},是一个程序员,我年龄是{1},我是{2}生,我的工作年限是{3}年", this.Name, this.Age, this.Gender, this.WorkYear);
}
public Programmer(string name,int age,char gender,int workYear) : base(name, age, gender)
{
this.WorkYear = workYear;
}
}
子类reporter
public class Reporter:Person
{
private string _hobby;
public string Hobby
{
get { return _hobby; }
set { _hobby = value; }
}
public void ReporterSayHello()
{
Console.WriteLine("我是{0},我是记者,我的爱好是{1},我是{2}生,我今年{3}岁了", this.Name, this.Hobby, this.Gender, this.Age);
}
public Reporter(string name,int age,char gender,string hobby) : base(name, age, gender)
{
this.Hobby = hobby;
}
}
主函数
static void Main(string[] args)
{
Reporter r = new Reporter("zs", 22, '男', "偷拍");
r.ReporterSayHello();
Programmer p = new Programmer("ls", 23, '男', 4);
p.ProgrammerSayHello();
Driver d = new Driver("ww", 35, '男', 15);
d.DriverSayHello();
Console.ReadKey();
}
结果
*里式转换
里式转换我们以后经常会用到,有两个点
Person p = new Student();
1.子类可以赋值给父类:如果有一个地方,需要父类作为参数,我们可以给一个子类代替
2.如果父类中装的是子类对象,那么可以将这个父类强转化为子类对象
Student ss = (Student)p;
is关键字
表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false。
if (p is Student)
{
Student ss = (Student)p;
ss.StudentSayHello();
}
else
{
Console.WriteLine("转换失败");
}
Console.ReadKey();
as关键字
表示类型转换,如果能够转换则返回对应的对象,否则返回一个null
//Teacher t = p as Teacher;
Student t = p as Student;
t.StudentSayHello();
Console.ReadKey();
里式转换练习
创建10个对象,通过一个循环去调用他们各自打招呼的方法
class Program
{
static void Main(string[] args)
{
//创建10个对象,通过一个循环去调用他们各自打招呼的方法
//Student s = new Student();
//Person p = new Person();
//ShuaiGuo sg = new ShuaiGuo();
Person[] pers = new Person[10];
Random r = new Random();
for (int i = 0; i < pers.Length; i++)
{
int rNumber = r.Next(1, 7);
switch (rNumber)//给数组赋值
{
case 1: pers[i] = new Student();
break;
case 2:pers[i] = new Teacher();
break;
case 3:pers[i] = new ShuaiGuo();
break;
case 4:pers[i] = new MeiLv();
break;
case 5:pers[i] = new YeShou();
break;
case 6:pers[i] = new Person();
break;
}
}
for (int i = 0; i < pers.Length; i++)
{
if (pers[i] is Student)
{
((Student)pers[i]).StudentSay();
}
else if (pers[i] is Teacher)
{
((Teacher)pers[i]).TeacherSay();
}
else if (pers[i] is ShuaiGuo)
{
((ShuaiGuo)pers[i]).ShuaiGuoSay();
}
else if (pers[i] is MeiLv)
{
((MeiLv)pers[i]).MeiLvSay();
}
else if (pers[i] is YeShou)
{
((YeShou)pers[i]).YeShouSay();
}
else
{
pers[i].PersonSay();
}
}
Console.ReadKey();
}
}
public class Person
{
public void PersonSay()
{
Console.WriteLine("我是人类");
}
}
public class Student:Person
{
public void StudentSay()
{
Console.WriteLine("我是学生");
}
}
public class Teacher:Person
{
public void TeacherSay()
{
Console.WriteLine("我是老师");
}
}
public class MeiLv : Person
{
public void MeiLvSay()
{
Console.WriteLine("我是美女");
}
}
public class ShuaiGuo : Person
{
public void ShuaiGuoSay()
{
Console.WriteLine("我是帅哥");
}
}
public class YeShou : Person
{
public void YeShouSay()
{
Console.WriteLine("我是野兽");
}
}
编码简介
编码就是将字符串以怎样的形式存为二进制
产生乱码的原因,就是你保存这个文件所采用的编码,跟你打开这个文件所采用的编码格式不一样。



