9.多态
Ploy的意思就是多于一种形式。在文章开始,方法那一章节就已经接触到了多态。多个方法名称相同,而参数不同,这就是多态的一种。
方法重载和方法覆盖就是用在了多态。多态有2中类型,一种是编译时多态,一种是运行时多态。
方法重载:
方法重载就是,多个方法拥有相同的方法名称,而参数个数或类型不同。
下面就是一个多态的例子,可以看到方法名称“BedRoom”被用到了2个方法中,就是2个方法有共同的方法名称"BedRoom",但是2个方法的参数是不同的。
1 class HouseOwnerClass 2 { 3 //Function with parameter 4 public void BedRoom(String nameandColor) 5 { 6 Console.WriteLine(nameandColor); 7 } 8 9 // Same Function Name with Different Paramenter10 public void BedRoom(String MemberName, String Color)11 {12 Console.WriteLine(MemberName + " Like " + Color + "Color");13 }14 15 static void Main(string[] args)16 {17 HouseOwnerClass objHouseOwner = new HouseOwnerClass();18 19 objHouseOwner.BedRoom("My Name is Shanu I like Lavender color");20 objHouseOwner.BedRoom("My Name is Afraz I like Light Blue color");21 objHouseOwner.BedRoom("SHANU", "Lavender");22 Console.ReadLine();23 24 }25 }
方法覆盖:
方法重载和方法覆盖的不同就是在于方法重载方法有相同的方法名称而参数不同。但是在方法覆盖中方法不仅有相同的方法名称,而且参数必须相同,返回值类型也相同。方法覆盖只能用在派生类中。 后面的章节我们就会看到方法重载和抽象方法,虚方法,密封方法之间的关系。
10.抽象类/方法
抽象类:抽象类就是给一个类前面加上"abstract"
abstract class GuestVist { }
抽象类是一个超级类。抽象类不能够被对象所访问,换句话说,抽象类是不能被实例化的。不能创建抽象类的对象。
那么我们创建一个抽象类的对象会怎么样呢?
抽象类可以包涵抽象方法和非抽象方法。在抽象类中至少要申明一个抽象方法。总而言之,派生类必须重写(override上面说的覆盖)抽象类非抽象方法。看下面的代码编译图片,会出现错误,意思是派生类必须实现父类的所有抽象方法。
下面我们看一个具体的例子来详细了解抽象方法。
1 abstract class GuestVist 2 { 3 public void Guestwelcomemessage() 4 { 5 Console.WriteLine("Welcome to our AbstractHome"); 6 } 7 public void GuestName() 8 { 9 Console.WriteLine("Guest name is: Abstract");10 }11 public abstract void purposeofVisit();12 13 }14 // derived class to inherit the abstract class15 public class Houseclass : GuestVist16 {17 static void Main(string[] args)18 {19 Houseclass objHouse = new Houseclass();20 objHouse.Guestwelcomemessage();21 }22 23 public override void purposeofVisit()24 {25 Console.WriteLine("Abstract just came for a Meetup and spend some time ");26 }27 }
在这个例子中我们可以看到在一个抽象类中,有普通的非抽象方法,和抽象方法。抽象类中,至少要有一个抽象方法。
11.虚类/方法
我们日常编程中虚方法是非常重要的。
那么什么是虚方法,我们要怎样使用虚方法呢?
继续我们的House示例:加入今天一共有5个人要来家里做客。那么我们写一个方法来显示5个客人要来访的信息。但是客人来的时候我们才发现来了20个人。一般情况下,当他们来之前,我们会知道来的人数增加还是减少。
在这种情况下,guest是一个独立的类,House 是另外一个类。为了不改变guest类里面的信息,我们要怎么通过派生类去改变数据呢?
抽象方法和虚方法有什么不同点?
两个都是用在覆盖重写方法的关键字。抽象方法只能被申明在抽象类里面。意思就是,抽象方法只能在抽象类中申明,而不能在抽象类中实现。然而虚方法能够实现。
看下面的程序:里面既有抽象方法又有虚方法。在抽象类中,虚方法里面说只有5个客人。但是在派生类中,该虚方法被override,说有20个客人。看下面的输出,结果会是虚方法里面的吗?到底是5个客人还是20个客人?测试一下便知。
1 abstract class GuestVist 2 { 3 public void Guestwelcomemessage() 4 { 5 Console.WriteLine("Welcome to our AbstractHome"); 6 } 7 public void GuestName() 8 { 9 Console.WriteLine("Guest name is: Abstract");10 }11 public abstract void purposeofVisit(); // Abstract Method 12 public virtual void NoofGuestwillvisit() // Virtual Method13 14 {15 Console.WriteLine("Total 5 Guest will Visit your Home");16 }17 }18 class AbstractHouseClass : GuestVist19 {20 public override void purposeofVisit() // Abstract method Override21 {22 Console.WriteLine("Abstract just for a Meetup and spend some time ");23 }24 25 public override void NoofGuestwillvisit() // Virtual method override26 {27 Console.WriteLine("Total 20 Guest Visited our Home");28 }29 30 static void Main(string[] args)31 {32 AbstractHouseClass objHouse = new AbstractHouseClass();33 objHouse.Guestwelcomemessage();34 objHouse.purposeofVisit();35 objHouse.NoofGuestwillvisit();36 Console.ReadLine();37 }38 }
结果是20个客人。
12.密封类/方法
密封类:指的是这个类不能够被其他的类所继承,就是该类不能有派生类。
继续看House示例。在一个房子里,主人有一个私密的小房间,可能是办公或者藏保险柜之类的~~哈哈密封类就用到了这里。、
密封类 的声明 用关键字 sealed,一旦有类被声明为sealed那么其他的派生类就不能够继承该类。
那么派生类继承了sealed类会发生什么? 看代码:
下面是一个完整的sealed类代码:
1 public sealed class OwnerofficialRoom 2 { 3 public void AllMyPersonalItems() 4 { 5 Console.WriteLine("All Items in this rooms are personal to me no one else can access or inherit me"); 6 } 7 } 8 class HouseSealedClass 9 {10 static void Main(string[] args)11 {12 OwnerofficialRoom obj = new OwnerofficialRoom();13 obj.AllMyPersonalItems();14 Console.ReadLine();15 }16 }
密封方法:如果我们声明一个密封方法,那么这个方法比较特殊,不能够被派生类重写(overrid)。
看house示例:类里面有虚方法和密封的虚方法。普通的虚方法能够被派生类重写,但是sealed虚方法不能够被派生类重写。
1 //Base Class with Sealed Method 2 public class OwnerOfficialroomwithrestriction 3 { 4 public virtual void message() 5 { 6 Console.WriteLine("Every one belongs to this house can access my items in my room except my sealed Item"); 7 8 } 9 10 public virtual sealed void myAccountsLoocker()11 {12 Console.WriteLine("This Loocker can not be inherited by other classes");13 }14 }15 //Deraived method which inherits Selaed Method class16 class HouseSealedClass : OwnerOfficialroomwithrestriction17 {18 public override void message()19 {20 Console.WriteLine("overrided in the derived class");21 }22 23 public override void myAccountsLoocker()24 {25 Console.WriteLine("The sealed method Overrides");26 }27 }
13.静态类/方法
已经讨论了密封类。下面来看看静态类和静态方法。静态类和密封类一样都不能够被继承。
那么静态类和派生类有何不同?
我们可以实例化密封类,在密封类章节可以看到我在main方法里面创建了一个对象来访问密封类。在密封类里,可以既有静态方法又有非静态方法。
但是静态类不能够被实例化,就是不能够创建静态类的对象。在静态类里只能存在静态成员。
main方法就是一个静态方法。当我们创建一个控制台应用程序的时候,会看到每个类都有一个main方法。这篇文章前面说过,main方法是最最最先被执行的。因为main方法被声明为static,所以不需要被实例化。
static void Main(string[] args) { }
有趣儿的是,静态方法,静态变量等在程序一开始执行就会分配相应的内存,而非静态的是在被实例化的时候分配内存的。
我们把密封类的例子修改成静态类的例子来看一下:
派生类继承静态类会发生什么?
我们在静态类中声明非静态方法又会怎样呢?
我们创建一个静态类的示例又会怎样呢?
运行程序会报错"Can not create an instance of a static class" 意思是不能够对静态类实例化,即不能创建静态类的对象。用的vs是韩版的so看到的是韩文。
那么不能够创建静态类的对象,我们改如何调用静态类里的方法和变量呢?
很简单,只需要用类名.方法名就可以了。看代码:
1 public static class OwnerofficialRoom 2 { 3 public static void AllMyPersonalItems() 4 { 5 Console.WriteLine("All Items in this rooms are personal to me no one else can access or inherit me"); 6 } 7 8 } 9 10 class HouseStaticClass 11 {12 static void Main(string[] args)13 {14 OwnerofficialRoom.AllMyPersonalItems();15 Console.ReadLine();16 17 }18 }
输出如下图:
能不能再非静态类中创建静态方法呢?yes
在非静态类里创建静态方法,和上面的调用方式一样,不需要对象去调用,直接用类名就可以了。
看下面的代码:
1 public class OwnerofficialRoom 2 { 3 public static void AllMyPersonalItems() 4 { 5 Console.WriteLine("No need to create object for me just use my class name to access me :)"); 6 } 7 8 public void non_staticMethod() 9 {10 Console.WriteLine("You need to create an Object to Access Me :(");11 }12 13 14 }15 16 class StaticmethodClass17 {18 static void Main(string[] args)19 {20 // for statci method no need to create object just call directly using the classname.21 OwnerofficialRoom.AllMyPersonalItems();22 23 // for non-static method need to create object to access the method.24 OwnerofficialRoom obj = new OwnerofficialRoom();25 obj.non_staticMethod();26 Console.ReadLine();27 28 }29 }
输出结果:
14.接口
接口和抽象类很相似,但是在接口里面只能存在方法的声明。而在抽象类中既可以声明方法,也可以实现方法。看代码:
1 interface GuestInterface 2 { 3 void GuestWelcomeMessage(); 4 void NoofGuestes(); 5 } 6 interface FriendsandRelationsInterface 7 { 8 void friendwelcomemessage(); 9 void FriendName();10 }11 12 class HouseOwnerClass : GuestInterface, FriendsandRelationsInterface13 {14 public void GuestWelcomeMessage()15 {16 Console.WriteLine("All guests are well come to our home");17 }18 19 public void NoofGuestes()20 {21 Console.WriteLine("Total 15 Guestes has visited");22 }23 24 public void friendwelcomemessage()25 {26 Console.WriteLine("Welcome to our Home");27 }28 public void FriendName()29 {30 Console.WriteLine("Friend name is: Afraz");31 }32 static void Main(string[] args)33 {34 HouseOwnerClass obj = new HouseOwnerClass();35 obj.GuestWelcomeMessage();36 obj.NoofGuestes();37 obj.friendwelcomemessage();38 obj.FriendName();39 Console.ReadLine();40 }41 }
看结果:
有时候我们确定有些方法派生类中要用,但是每个派生类对该方法的需求不同,那么就可以使用接口,把该方法写到接口里面,让每个派生类自己去实现自己的需求。
在抽象类中,可以有抽象方法也可以有非抽象方法。但是接口里的所有方法都被默认为抽象方法,所有在接口中声明的方法,在派生类中都必须实现。
一个接口的代码:
1 interface GuestInterface 2 { 3 void GuestWelcomeMessage(); 4 void NoofGuestes(); 5 } 6 class HouseOwnerClass: GuestInterface 7 { 8 public void GuestWelcomeMessage() 9 {10 Console.WriteLine("All guests are well come to our home");11 }12 13 public void NoofGuestes()14 {15 Console.WriteLine("Total 15 Guestes has visited");16 }17 18 static void Main(string[] args)19 {20 HouseOwnerClass obj = new HouseOwnerClass();21 22 obj.GuestWelcomeMessage();23 obj.NoofGuestes();24 Console.ReadLine();25 }26 }
终于完啦~~~~~