概念:

在上一节课中学习了如何定义类,用类当做模板来声明我们的数据。

很多类中有相似的数据,比如在一个游戏中,有Boss类,小怪类Enemy,这些类他们有很多相同的属性,也有不同的,这个时候我们可以使用继承来让这两个类继承自同一个类。

分类:

实现继承: 表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。 在实现继承中,派生类型采用基类型的每个函数的实现代码,除非在派生类型的定义中指定重写某个函数的实现代码。 在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承非常有用。

接口继承: 表示一个类型只继承了函数的签名,没有继承任何实现代码。 在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。

多重继承:

C#不支持多重实现继承。 而 C#允许类型派生自多个接 口— — 多重接口继承。 这说明,C#类可以派生自另一个类和任意多个接口。更准确地说, System.Object 是一个公共的基类,所 以每个 C#(除了Object类之外)都有一个基类,还可以有任意多个基接 口。

实现继承:

如果要声明派生自另一个类的一个类,就可以使用下面的语法:
class MyDerivedClass : MyBaseclass
{
// functions and data members here
}
如果类(或 结构)也 派生 自接 口,则用逗号分隔列表中的基类和接 口:
public class MyDerivedClass: MyBaseClass , IInterface1 , IInterface2
{
// etc.
}

接口继承:

namespace _012_定义和实现接口 {
interface IA //不能有字段,方法不能被实现
{
void Method1();
}
} namespace _012_定义和实现接口 {
interface IB:IA
{
void Method2();
}
} namespace _012_定义和实现接口 {
interface IFly
{
void Fly();
void MethodA();
}
}
//继承了接口就要实现继承的接口中的所有方法,包括接口的父接口中的方法
namespace _012_定义和实现接口 {
class Bird :IFly,IB{
public void Fly()
{ } public void MethodA()
{ } public void Method1()
{ } public void Method2()
{ }
}
}

虚方法:

把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:
class MyBaseClass{
public virtual string VirtualMethod(){
return "Method is called in base class";
}
}
在派生类中重写另外一个函数时,要使用override关键字显示声明
class MyDerivedClass:MyBaseClass{
public override string VirtualMethod(){
return "Method is called in derivedclass.";
}
}
我们在子类里面重写虚函数之后,子类对象不管在哪里调用都是调用重写之后的方法,可以不重写,不重写就调用父类的方法,将子类对象赋给父类对象也会调用子类中重写的方法

隐藏方法(密封方法):

如果签名相同的方法在基类和派生类中都进行了声明,但是该方法没有分别声明为virtual和override,派生类就会隐藏基类方法。(要使用new关键字进行声明)
基类
class MyBaseClass{
public int MyMethod(){
}
}
派生类(在派生类中把基类同名的方法隐藏掉了)
class MyDerivedClass :MyBaseClass{
public new void MyMethod() //有没有new都可以,只是表示是隐藏方法,但是父类的方法还是存在的,重写的话父类的方法在子类中是不存在了
{
}
}

Enemy enemy;
enemy = new Boss();//父类声明的对象,可以使用子类去构造 子类声明的对象不可以使用父类构造
//enemy虽然使用父类进行了声明,但是使用了子类构造,所以本质上是一个子类类型的,我们可以强制类型转换转换成子类类型
Boss boss = (Boss)enemy;
boss.Attack();

 

Enemy enemy = new Enemy();
Boss boss =(Boss) enemy;//一个对象是什么类型的 主要看它是通过什么构造的 这里enemy使用了父类的构造函数,所以只有父类中的字段和方法, 不能被强制转换成子类


Enemy boss = new Boss();
boss.Move();//隐藏方法: 如果使用子类声明的对象,调用隐藏方法会调用子类的,如果使用父类声明对象,那么就会调用父类中的隐藏方法

this和base关键字:

this可以访问当前类中定义的字段,属性和方法,有没有this都可以访问,有this可以让IDE-VS编译器给出提示,另外当方法的参数跟字段重名的时候,使用this可以表明访问的是类中的字段。

base可以调用父类中的公有方法和字段,有没有base都可以访问,但是加上base.IED工具会给出提示,把所有可以调用的字段和方法罗列出来方便选择

使用base关键字调用父类构造函数的语法如下:
子类构造函数:base(参数列表)
使用base关键字调用父类方法的语法如下:
base.父类方法();
using System ;
class Teacher//老师类
{
public Teacher()//构造函数1
{
Console.WriteLine ("我是一位教师。");
}
public Teacher(string str)//构造函数2
{
Console.WriteLine ("老师,"+str);
} public void OutPut()//自定义方法
{
Console.WriteLine ("输出方法");
} private string name;
public string Name//属性
{
get{return this.name;}
set{this.name=value;}
}
public void getName()
{
Console.WriteLine ("我的名字是"+name);
}
} class Jack:Teacher
{
static string hello="你好";
public Jack():base(hello)//子类的构造函数继承的为父类第二个构造函数,注意写法
{
}
public void myOutPut()//自定义函数
{
base.OutPut ();//引用父类的函数
}
public string myName//自定义属性
{
get{return base.Name ;}
set{base.Name ="王"+value;}
}
}
class Test
{
static void Main()
{
Jack j=new Jack ();//输出“老师,你好”
j.myOutPut ();//输出"输出方法"
j.myName ="猫骨";
j.getName ();//输出“王猫骨”
}
}
注意:base()调用父类构造函数时,不需要再次指定参数的类型,因为在子类中已经定义了这些参数,在base()中只需指定变量名即可,参数的类型必须和父类中的一致。

抽象类:

C#允许把类和函数声明为 abstract。 抽象类不能实例化,抽象类可以包含普通函数和抽象函数,抽象函数就是只有函数定义没有函数体。 显然,抽象函数本身也是虚拟的Virtual(只有函数定义,没有函数体实现)。
类是一个模板,那么抽象类就是一个不完整的模板,我们不能使用不完整的模板去构造对象。,但是可以声明对象
  abstract class Bird//一个抽象类 就是一个不完整的模板
{
private float speed; public void Eat()
{ } public abstract void Fly();//抽象方法,没有实体
} class Crow:Bird {//我们继承了一个抽象类的时候,必须去实现抽象方法
public override void Fly()
{
Console.WriteLine("乌鸦在飞行");
}
}

密封类和密封方法:

C#允许把类和方法声明为 sealed。 对于类 ,这表示不能继承该类;对于方法表示不能重写该方法。
sealed FinalClass
{
// etc
}
什么时候使用 密封类和密封方法?
防止重写某些类导致代码混乱,在重写的方法override前加sealed
商业原因

派生类的构造函数:

,在子类中调用父类的默认构造函数(无参)(会先调用父类的,然后是子类的)
public class MyDerivedClass{
public MyDerivedClass():base(){
//do something
}
}
在这里 :base()可以直接不写,因为默认会调用父类中的默认构造函数
,调用有参数的构造函数
public class MyDerivedClass{
public MyDerivedClass(string name):base(name){
//do something
}
}

修饰符:

修饰符,用来类型或者成员的关键字。修饰符可以指定方法的可见性。

public 和private修饰字段和方法的时候,表示该字段或者方法能不能通过对象去访问:

只有public的才可以通过对象访问

private(私有的)只能在类模板内部访问。

protected 保护的,当没有继承的时候,它的作用和private是一样的,当有继承的时候,protected表示可以被子类访问的字段或者方法

类型的修饰符:

public class ...

class ...

前者可以在别的项目下访问,后者不行

其他修饰符:

static可以修饰字段或者方法,修饰字段的时候,表示这个字段是静态的数据,叫做静态字段或者静态属性,修饰方法的时候,叫做静态方法,或者静态函数 使用static修饰的成员,只能通过类名访问 当我们构造对象的时候,对象中只包含了普通的字段,不包含静态字段

实现继承+接口继承+虚方法+隐藏方法+this/base+抽象类+密封类/方法+修饰符的更多相关文章

  1. python的类的继承-接口继承-归一化设计

    1.先在子类本身找,如果子类没有,会去父类找 class Dad: '这个是爸爸类' money=10#Dad类的数据属性 def __init__(self,name): print("爸 ...

  2. this/super/static/final/匿名对象/继承/抽象类/访问权限修饰符

    1.this关键字的作用     1)调用本类中的属性;     2)调用本类中的构造方法;且只能放首行,且必须留一个构造方法作为出口,即不能递归调用     3)表示当前对象; 2.匿名对象     ...

  3. java 面对对象(抽象 继承 接口 多态)

    什么是继承? 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可. 多个类可以称为子类,单独这个类称为父类.超类或者基类. 子类可以直接 ...

  4. JAVA中方法和变量在继承中的覆盖和隐藏

    出处:http://renyanwei.iteye.com/blog/258304 我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际 ...

  5. JAVA中方法和变量在继承中的覆盖和隐藏(一)

    我们知道,在JAVA中,子类可以继承父类,如果子类声明的方法与父类有重名的情况怎么办,大伙儿都知道要是重写,但是实际上这又分为两种情况,就是方法和变量在继承时的覆盖和隐藏问题,这些概念性的东西看似无聊 ...

  6. python之接口继承

    接口继承 接口继承就是(基类)父类定义好2个函数属性(接口),所有的子类必须有这2个函数属性,缺一不可,不是说省代码的,是用来做强制性约束的 基类里面的方法不用具体的实现,只是一个规范而已 1.1实现 ...

  7. .NET C#基础(2):方法修饰符 - 给方法叠buff

    0. 文章目的   本文面向有一定.NET C#基础知识的学习者,介绍C#中的方法修饰符的含义和使用以及注意事项.   1. 阅读基础   理解C#基本语法(如方法声明)   理解OOP基本概念(如多 ...

  8. 【译文】 C#面向对象的基本概念 (Basic C# OOP Concept) 第一部分(类,对象,变量,方法,访问修饰符)

    译文出处:http://www.codeproject.com/Articles/838365/Basic-Csharp-OOP-Concept 相关文档:http://files.cnblogs.c ...

  9. Java中各种(类、方法、属性)访问修饰符与修饰符的说明

    类: 访问修饰符 修饰符 class 类名称 extends 父类名称 implement 接口名称 (访问修饰符与修饰符的位置可以互换) 访问修饰符 名称 说明 备注 public 可以被本项目的所 ...

随机推荐

  1. docker related,docker history

    History of an image and size of layers: docker history --no-trunc=true zabbix/zabbix-3.0 | tr -s ' ' ...

  2. CalendarUtil 日期操作工具类

    版权声明:本文为博主原创文章,未经博主允许不得转载. [java] view plain copy import java.util.Calendar; import java.text.DateFo ...

  3. python并发编程&多线程(二)

    前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链 ...

  4. tomcat8.5.11的manager页面总是提示403的问题

    修改conf/tomcat-users.xml加入: <role rolename="manager"/> <role rolename="manage ...

  5. CoreThink主题开发(九)使用H-ui开发博客主题之用户个人主页

    感谢H-ui.感谢CoreThink!  效果图: 这里使用table布局 /Theme/Blog/User/Index/home.html <extend name="$_home_ ...

  6. EasyMock 常见异常

    1. java.lang.IllegalStateException: calling verify is not allowed in record state 含义:不允许在记录状态(record ...

  7. 函数没有返回值,默认返回undefined

    var  a =( function(){return})(); a = undefined;

  8. iOS oc 调用 swift

    如股票oc要调用swift里面的代码 需要包含固定这个头文件 项目名称 LiqunSwiftDemo-Swift.h #ProjectName#-Swift.h 固定的写法 swift 目的 是取代o ...

  9. UIPageControl修改圆点大小,根据View大小自适应

    遇到了个基本的控件问题,当设置UIPageControl的frame很小时,上面的小圆点会忽视view的frame而将圆点显示到控件外面. 但是如果想要设置小一点的圆点,或改变圆点间的间距,从而实现自 ...

  10. sudoers文件设置sudo命令无密码(root密码)登录

    参考博客:http://xvshell.iteye.com/blog/1838093 1. 当用户执行sudo时,Linux系统会去寻找/etc/sudoers文件,并且这是主动的,判断用户是否有执行 ...