01 object类的ToString()和GetType()简单了解
object类中的ToString()和GetType()功能
ToString()//返回项目名+“.”+类名
GetType()//也是返回项目名+“.”+类名
但是ToString()是虚方法,通常我们在常用的应用类中重写了ToString(),使其将其他类型变量转换成字符串类型。但我们自己写的类中ToString()依然是继承object()的功能,所以在 自定义的对象中调用ToString()方法时要注意。
而GetType()不是虚方法是不能重写的,所有的类都继承object,所以所有的类都能调用这个方法,功能是一致的,刚才查了,一般的常用的类都写了一个GetTypeCode()方法,用 于返回对象的类名。
02里氏替换原则----类型转换
父类应用指向子类对象 person p=new chinese()//其实是发生了隐式类型转换。虽然通过p我们可以调用chinese的内容,这些方法 字段 属性是从chinese类中继承 的,故可以用p进行访问,而chinese类中非继承的方法 属性 字段是不能被p调用的。
强制类型转换是:person p=new chinese();//p本身就是指向chinese类的,所以是可以再转换成chinese类的
chinese sp=(chinese) p;//转换出错会报异常
as 类型转换 person p=new chinese()
chinese sp=p as chinese//用as进行强制类型转换即使出错也不会报异常,如果出错sp=null
***** is ******
if(sp is chinese)//检验sp是否是chinese类
03多态:个人理解是不同的对象在收到相同的消息时,会采取不同的措施。
实现多态的三个方法:1,通过虚方法实现
2,通过抽象类实现
3,通过接口实现
1:通过虚方法实现
注意:虚方法用virtual标记,virtual只能修饰方法,
父类的虚方法子类可以继承也可以重写,重写要用override
子类对象再调用虚方法时,先检测虚方法是否重写,如果重写就执行重写的方法,未重写就执行父类的虚方法
代码:
public class Person
{
private string name;
private int age;
private string sex;
public Person()
{
}
public Person(string _name,int _age,string _sex)
{
this.Name = _name;
this.Age = _age;
this.Sex = _sex;
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
public string Sex
{
get
{
return sex;
}
set
{
sex = value;
}
}
public virtual void Say()
{
Console.WriteLine("我是地球人");
}
}
public class Chinese:Person
{
public Chinese(string _name,int _age,string _sex):base(_name,_age,_sex)
{
}
public Chinese()
{
}
public override void Say()
{
Console.WriteLine("我是中国人");
}
}
public class Merican:Person
{
public Merican(string _name, int _age, string _sex):base(_name,_age,_sex)
{
}
public override void Say()
{
Console.WriteLine("i from merican");
}
}
public class BeiJing:Chinese
{
public BeiJing (string _name,int _age,string _sex):base(_name,_age,_sex)
{
}
public override void Say()
{
Console.WriteLine("我是北京人");
}
}
class Program
{
static void Main(string[] args)
{
Chinese sd = new Chinese("张三",22,"男");
Merican sf = new Merican("tom",33,"man");
BeiJing sa = new BeiJing("李四",11,"男");
Person[] sx = new Person[] { sd,sf,sa};
foreach (var item in sx)
{
Console.WriteLine("{0},{1},{2}",item.Name,item.Age,item.Sex);
item.Say();
}
Console.ReadKey();
}
}

2:使用abstract实现多态
抽象类注意点: 1.抽象成员必须在抽象类中,用abstract修饰,且抽象成员不能有任何实现功能
2 抽象类可以有非抽象成员
3 抽象类只能被继承,不能被实例化,
4抽象类不能用private来修饰
5抽象类的子类要实现父类的抽象成员的方法或字段,除非子类也是抽象类,实现用override关键字
注:再父类不需要被实例化时,用抽象类实现多态,如果父类需要被实例化成对象,则用虚方法实现多态
a--b--c:a是父类,a中的抽象方法不能有认识实现,抽象成员必须在b中重写,c继承b类可以重写也可以不重写。如果b也是抽象类,则b可以重写a中的抽象成员 也可以, 也可不写,c要写B中的抽象成员,如果b未写a中的抽象成员,则c必须重写a中的抽象方法。
代码:
public abstract class Person
{
public abstract void SayHello();
public abstract void StandUp();
}
public class Teacher : Person
{
public override void SayHello()
{
Console.WriteLine("同学们好");
}
public override void StandUp()
{
Console.WriteLine("请坐");
}
}
public class Student:Person
{
public override void SayHello()
{
Console.WriteLine("老师好");
}
public override void StandUp()
{
Console.WriteLine("谢谢老师");
}
}
class Program
{
static void Main(string[] args)
{
Student student = new Student();
Teacher teacher = new Teacher();
student.SayHello();
teacher.SayHello();
teacher.StandUp();
student.StandUp();
Console.ReadKey();
}
}

3:接口实现多态
接口:接口可以理解为是一种规范,他与抽象类很类似,但类具有单根性,只能继承一个父类,但类可以实现多个接口,所以利用接口来解决这个问题。
抽象类解决的是同一类中具有同一功能,但具体实现方法不同的问题
接口实现的是不同类具有相同功能,但具体实现方法不同的问题
接口的使用规范:1>接口类只能有方法(属性 索引器 函数 事件),不能有访问修饰符,但默认接口类的方法都是public(其实接口的访问权限只能是 public internal,所以接口类的方法的访问权限实际上实在这二者之间的)
2> 接口中的方法,不能有任何实现,类在实现接口时,必须要将类中的方法重写,除非这个类是抽象类,抽象类可以选择实现也可以选择 不实现,不实现的话,要用abstract将方法重新定义一下。
3>接口和抽象类一样只可以继承,不可以实例化(new),一个类可以继承多个方法。
4>类在继承接口和类时,类要写在接口的前面,类和类之间可以继承,类和接口之间是实现,接口和接口之间也可以继承
5>接口的功能要尽量单一,避免接口污染
代码:
父类
public abstract class Bird
{
public abstract void Have();
public abstract void Eat();
}
接口
public interface IFlyable
{
void Fly();
}
接口
public interface IRunable
{
void Run();
}
子类
public class Ostrich : Bird,IRunable
{
private int al;
public int a2;
public override void Eat()
{
Console.WriteLine("鸵鸟吃草");
}
public override void Have()
{
Console.WriteLine("驼鸟有翅膀");
}
public void Run()
{
Console.WriteLine("鸵鸟会跑");
}
}
子类
public class Sparrow : Bird, IFlyable
{
public override void Eat()
{
Console.WriteLine("麻雀吃虫");
}
public void Fly()
{
Console.WriteLine("麻雀会飞");
}
public override void Have()
{
Console.WriteLine("麻雀有翅膀");
}
}
主函数
static void Main(string[] args)
{
Sparrow sparrow = new Sparrow();
sparrow.Eat();
sparrow.Fly();
sparrow.Have();
Ostrich ostrich = new Ostrich();
ostrich.Eat();
ostrich.Have();
ostrich.Run();
Console.ReadKey();
}
关于实例化的一些问题:person(抽象父类) Student(子类) Study(接口)
abstract person
interface Study
Student:person
student sb=new student()//实例化对象,sb可以调用Student中的所有可以调用的方法,字段
person sd=new student()// 将一个Student 对象隐式转换未person类型的变量并赋予sd,sd可以调用Student中继承的Person所有方法 字段
调用执行的方法是子类重写的方法
Study sf=new student()//将一个Student 对象隐式转换未Study类型的变量并赋予sf,sf可以调用Student中继承的Person所有方法 字段
调用执行的方法是子类重写的方法
父类中的方法子类继承后想把父类继承的方法隐藏,并还用这个方法名写一些功能: 可以用new关键子隐藏父类成员,这样子类对象要用这个方法调用的是子类重写的方 法,但像person sd=new student()这样,sd调用的依然是父类的这个方法。因为, 首先new关键子重写的方法虽然名字相同,但本质上已是一个新的方法,与父类毫无 关系,父类变量无法调用他,其次子类中未重写这个方法,这系统会调用父类的这 个方法
代码:
父类
public class Penson
{
public virtual void SayHi()
{
Console.WriteLine("我是你爸爸");
}
}
子类
public class Chinese:Penson
{
public new void SayHi()
{
Console.WriteLine("我是你儿子");
}
}
主函数:
static void Main(string[] args)
{
Penson sb = new Chinese();
sb.SayHi();
Chinese sd = new Chinese();
sd.SayHi();
Console.ReadKey();
}

显示实现接口:继承的多个接口中方法名相同,可以用显示接口来解决这个问题,
显示接口实现:访问权限是私有的,重写是要用接口名+“.”+方法名,调用时要将类转换成接口,利用接口调用
要注意显示显示接口怎么实现,和怎么调用重写的显示接口
例子:
public interface Iexercise
{
void Swimming();
}
public interface Relax
{
void Swimming();
}
public class Student :Iexercise, Relax
{
public void Swimming()
{
Console.WriteLine("我要练习游泳");
}
void Relax.Swimming()//显示实现接口,访问权限是私有的,重写是要用接口名+“.”+方法名,调用时要将类转换成接口,利用接口调用
{
Console.WriteLine("放松时我想去游泳");
}
static void Main(string[] args)
{
Student student = new Student();
Relax relax = new Student();
student.Swimming();
relax.Swimming();
Console.ReadKey();
}

浙公网安备 33010602011771号