南阳市网站建设,做企鹅号的视频素材网站,默认线路正在切换线路,wordpress添加文章目录基本概念
继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类#xff0c;这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
当创建一个类时#xff0c;程序员不需要完全重新编写新的数据成员和成员函数#xff0…基本概念
继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。
当创建一个类时程序员不需要完全重新编写新的数据成员和成员函数只需要设计一个新的类继承了已有的类的成员即可。这个已有的类被称为的基类这个新的类被称为派生类。基类有时又叫父类、超类派生类有时又叫子类。
在逻辑上可以认为派生类属于基类例如在描述图像时可以用图形Shape作为基类正方形Square作为派生类此时有正方形属于图形的从属关系。
需要注意的是C#不支持多重继承。意思就是一个派生类只能继承一个基类。当然基类也可以继承自其它的基类。
继承语法如下
class BaseClass{//BaseClass基类成员
}
class DerivedClass : BaseClass{//DerivedClass派生类成员
}
一般会在派生类名后添加冒号加基类名表示派生类继承于基类。
sealed
默认情况下所有类都可以通过继承得到。但是你可以指定某个类不能作为基类或是指定某个类只能用作基类。例如指定类A不能作为基类
public sealed class A {//A类成员
}
此时我们使用关键字sealed将类限定为密封类sealed修饰符将阻止其他类继承此类。可以简单理解为sealed关键字使其他类不能继承于类A。一般称sealed关键字修饰的类为密封类。
abstract
当使用关键字abstract修饰某一类则该类只能作为基类不能被实例化。例如指定类B不能被实例化类C继承于类B
public abstract class B{//类B的成员
}
public class C : B{//类C的成员
}
实际上abstract修饰符表明所修饰内容尚未完全实现。abstract修饰符也可用于函数、属性、索引和事件等被abstract限定的类成员或包含在abstract类中的成员必须由继承此类的子类实现
例如下面的实例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace K1
{public abstract class Shape //基类Shape表示形状{public abstract int Area(); //获取形状面积成员函数未完全实现}public class Square : Shape //派生类Square表示正方形{int side;public Square(){side 0;}public Square(int side){this.side side;}public override int Area() //在派生类中成员函数Area实现。{return side * side;}}public class myCaller{public static void Main(string[] args){string side Console.ReadLine();Square s new Square(Convert.ToInt32(side));Console.WriteLine(Square Area: s.Area());Console.ReadKey();}}
}需要注意子类的访问级别不能高于基类上面的基类Shape与派生类Square均为public访问级别符合规则。上面实例输入输出如下所示 10 Square Area:100 代码中定义的基类Shape以及其中成员函数Area使用abstract修饰故Shape类必须作为基类且成员函数Area必须在派生类Square中实现。
abstract类可称为抽象类抽象类有如下性质
抽象类不能被实例化抽象类可能包含抽象方法和抽象存取器抽象类不能被sealed修饰sealed和abstract作用意义互相冲突。使用sealed修饰的类不能被继承使用abstract修饰的类只能被继承继承自抽象类的子类必须实现抽象类中声明的抽象函数和抽象存取器。
在函数或属性声明处使用abstract修饰符用来表明该函数或属性不可实现。abst\fract修饰的函数有如下几个特点
抽象方法声明只允许在抽象类中使用由于抽象方法没有提供具体的实现过程所以不需包含函数体方法声明以;结尾不需使用{};具体的实现过程将会在子类中使用override标志在抽象方法声明中不允许使用static或virtual抽象方法是一种隐式的虚函数virtual method。
抽象属性表现类似于抽象方法除了声明和调用语法的不同之外
在静态(static修饰)属性中不可使用abstract修饰符在基类中声明的抽象属性可继承到子类中。并使用override重写。
override
上面的实例在派生类Square中的成员函数Area中涉及到另外一个关键字overrideoverride修饰符用来拓展或修改继承自基类中的方法、属性、索引或事件其中基类中的方法、属性、索引或事件使用abstract或virtual修饰。
其中override重写实现的方法声明必须与基类中方法拥有相同的函数签名。
override不能重写非虚方法或静态方法抽象方法是一种隐式的虚方法在基类中的方法必须使用virtual、abstract或override修饰。
使用override修饰方法声明不能更改继承基类虚方法的访问修饰符两者需保持一致。
在使用override修饰的方法时不能够使用修饰符new、static或virtual。使用override修饰的属性类似。
多态
多态可理解为多种形态在派生于同一个类的不同子类对象上执行任务操作时多态性十分的高效使用的代码最少。只要在继承层次中有一个相同多的类那么就可使用多态性进行处理。
下面的代码实例可体现多态使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace K2
{public abstract class Shape //基类Shape{public abstract int Area(); //获取形状面积}//派生类圆形Circular类和正方形Square类public class Circular : Shape{int radius; //成员radius表示圆形半径public Circular(int radius){this.radius radius;}public override int Area() //重写基类成员函数{return radius * radius * 3;}public void radiusSet(int radius){this.radius radius;}}public class Square : Shape{int side; //成员side表示正方形边长public Square(int side){this.side side;}public override int Area(){return side * side;}}public class myCaller{public static void Main(string[] args){Circular c new Circular(4);Square s new Square(4);Shape shape1 s; //子类对象可被当做基类对象使用Shape shape2 c;Console.WriteLine(Square Area: shape1.Area()); //多个子类便可提供多种Area实现Console.WriteLine(Circular Area: shape2.Area());}}
}
多态有多种应用场景
一、子类对象可被当做基类对象使用
在运行时子类对象可被当做基类对象使用例如当对象用于方法参数、集合或数组的时候该对象的声明类型不再与运行时类型相同。例如上面的实例中Shape类对象接受Circular类对象、Square类对象无需强制类型转换。此时对象shape2不能使用Circular类中的成员函数RadiusSet如果想要调用可以使用强制类型转换将Shape类对象转换回Circular类对象。
Circular c2(Circular)shape2;
c2.RadiusSet(10);
二、子类可提供多种基类方法实现
使用继承的时候子类可使用override重写基类中定义和实现的虚方法多个子类便可提供多种实现。在运行时当客户端代码调用该方法的时CLR查询对象的运行时类型会调用重写的虚方法。所以源码中可通过调用基类中的方法具体执行的则是子类中已重写的方法。
例如上面的实例子类便使用override重写了基类中定义的Area方法此后Shape类对象分别接受s、c调用Area方法时Shape1使用的是Square类中实现的方法Shape2使用的是Circular类实现的方法。