继承
当在主函数中new
了一个子类的对象时,子类对象的初始化会先调用父类
的无参构造方法,再调用子类
的当前构造方法。
using System;
namespace ConsoleApp6
{
class animal
{
public animal()
{
Console.WriteLine("animal无参构造函数");
}
public animal(string str)
{
Console.WriteLine("animal带参构造函数");
}
}
//继承
class Dog:animal
{
public Dog()
{
Console.WriteLine("Dog无参构造函数");
}
public Dog(string str)
{
Console.WriteLine("Dog带参构造函数");
}
}
}
<img src="C:\Users\Hab_L\Desktop\1.JPG" alt="无参数对象" style="zoom:80%;" />
<img src="C:\Users\Hab_L\Desktop\2.JPG" alt="2" style="zoom:80%;" />
所有如果在父类中如果定义了带参数的构造方法,必须定义一个无参构造方法(即使方法体为空),否则子类对象数据在初始化时,调用父类的无参构造方法会出错。
using System;
namespace ConsoleApp6
{
class animal
{
/*public animal()
{
Console.WriteLine("animal无参构造函数");
}*/
public animal(string str)
{
Console.WriteLine("animal带参构造函数");
}
}
//继承
class Dog:animal
{
public Dog()
{
Console.WriteLine("Dog无参构造函数");
}
public Dog(string str)
{
Console.WriteLine("Dog带参构造函数");
}
}
}
当我注释了父类
无参构造函数之后,程序立马报错。
<img src="C:\Users\Hab_L\Desktop\3.JPG" alt="3" style="zoom:80%;" />
多态
-
判断一个对象是什么类型,看他
new
的类型是什么,包括new
的类型和他的父类型。 -
子类型向父类型自动转换,父类型向子类型转换需要强制转换
as
。 -
声明变量的类型,决定了变量的访问成员的范围。
using System; namespace ConsoleApp6 { class animal { string name; public animal() { Console.WriteLine("animal无参构造函数"); name = "a"; } public animal(string str) { Console.WriteLine("animal带参构造函数"); this.name = str; } public void say() { Console.WriteLine("animal say"); } } //继承 class Dog:animal { public Dog() { Console.WriteLine("Dog无参构造函数"); } public Dog(string str):base(str) { Console.WriteLine("Dog带参构造函数"); } public new void say() { Console.WriteLine("Dog say"); } } }
static void Main(string[] args)
{
animal a1 = new Dog("d");
a1.say()//这里就只能调用animal的say方法
}
-
但是如果用
virtual
关键字定义父类方法,override
关键字定义子类方法,则上个例子中调用的就是子类的say方法。using System; namespace ConsoleApp6 { class animal { string name; public animal() { Console.WriteLine("animal无参构造函数"); name = "a"; } public animal(string str) { Console.WriteLine("animal带参构造函数"); this.name = str; } public virtual void say()//virtual关键字 { Console.WriteLine("animal say"); } } //继承 class Dog:animal { public Dog() { Console.WriteLine("Dog无参构造函数"); } public Dog(string str):base(str) { Console.WriteLine("Dog带参构造函数"); } public override void say()//override关键字 { Console.WriteLine("Dog say"); } } }
static void Main(string[] args) { animal a1 = new Dog("d"); a1.say();//这里调用的就是Dog的say方法 }
如果需要调用父类的say方法,则在子类的say方法中添加
base.say()
public override void say() { base.say(); Console.WriteLine("Dog say"); }
这个时候
animal
的say()
和Dog
的say()
都会被执行。总结多态
声明变量时声明为父类型的,但是指向子类型的对象,可以使用
is
做判断,as
做转换。方法重写分别使用virtual
和override
关键字。
静态static
- 面向对象互斥的一个概念
- 不需要得到对象实例,直接使用类调用成员。在运行期间会一直存在内存中,并且是唯一的。
- 可以用来修饰类、方法、字段
- 静态类不可以继承
- 可以在访问修饰符访问的范围内直接访问。
抽象类
-
抽象方法必须在抽象类中
-
抽象类中可以有带方法体的方法
-
当方法在父类中的具体实现没有意义时,使用抽象方法
-
抽象类不能被实例化,但是可以得到一个子类对象
例如:
using System; namespace ConsoleApp6 { abstract class animal//声明抽象类 { public abstract void jiaofa();//抽象方法必须在抽象类中 } class Dog:animal { public override void jiaofa()//继承抽象类必须实现抽象类的抽象方法 { Console.WriteLine("汪汪"); } } }
-
在抽象类中定义构造方法的意义:让子类调用
using System; namespace ConsoleApp6 { abstract class animal//声明抽象类 { public string astr; public animal(string str)//animal的构造函数 { this.astr = str; } public abstract void jiaofa();//抽象方法必须在抽象类中 } class Dog:animal { public Dog(string str):base(str)//构造函数 { Console.WriteLine(str); } public override void jiaofa()//继承抽象类必须实现抽象类的抽象方法 { Console.WriteLine("汪汪"); } } }
接口
-
在接口中只定义了方法的签名,没有定义代码段(所有的方法都是抽象的)
-
一个类可以实现多个接口,使用冒号连接
-
弥补了类单继承的缺陷
-
接口之间也可以有继承关系
-
类既有函数成员又有数据成员,接口只有函数成员
//Ijiaofa.cs 接口文件 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp6 { interface Dogjiao { void Dogjiao(); } interface Catjiao { void Catjiao(); } interface Ijiaofa:Dogjiao,Catjiao//不同的动物叫法 { void alljiao(); } }
//animal.cs 抽象类 using System; namespace ConsoleApp6 { abstract class animal//声明抽象类 { } class Dog:animal,Dogjiao//狗 { public void Dogjiao() { Console.WriteLine("汪汪!"); } } class Monster : animal, Ijiaofa//怪物,什么都会叫 { public void alljiao() { Console.WriteLine("wu wu!"); } public void Catjiao() { Console.WriteLine("miao miao!"); } public void Dogjiao() { Console.WriteLine("wang wang!"); } } }
//主函数 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp6 { class Program { static void Main(string[] args) { Dogjiao dogjiao = new Dog();//实现多态 dogjiao.Dogjiao(); Console.WriteLine(); Ijiaofa ijiaofa = new Monster();//它有三个方法可以访问 ijiaofa.alljiao(); ijiaofa.Catjiao(); ijiaofa.Dogjiao(); } } }
枚举
标识枚举:让二进制中的某一位为1,剩下的都为0
[Flags]
public enum Layer
{
default1 = 1<<0,
red = 1<<1,
blue = 1<<2,
green = 1<<3
//左移表示×2的n次方
}
网友评论