继承、接口、虚方法、抽象类

来源:互联网 发布:蚁群算法解决指派问题 编辑:程序博客网 时间:2024/05/29 13:58

一、继承

   把公有的数据或方法放在父类中,在子类中放不同的属性,子类继承父类
   
例子:
     class DiRen
    {
     public void AI()
        {
            Console.WriteLine("这是敌人公有的AI方法");
        }
}

class Boss:DiRen
    {
        public void Attack()
        {
            Console.WriteLine("Boss正在进行攻击");
        }
    }
Boss boss = new Boss();
     boss.AI();
 
描述:Boss类继承DiRen类,所以能调用DiRen类中的AI方法
      如果方法或字段是私有的,则不能调用
  
DiRen diren;
     diren = new Boss();
     父类声明的对象可以用子类去构造
但不能使用子类中的方法,如: diren.Attack(); 需要使用强制转换
Boss boss = (Boss)diren;
boss.Attack();
 
DiRen diren = new DiRen();
用父类构造的对象无法强制转换为子类,如:Boss boss = (Boss)diren;
 
 

二、虚方法

     父类中关键字: virtual     放在访问修饰符后面
子类中关键字: override
有共同的方法但方法中体现的代码不同可以使用虚方法,在子类中重写方法
注意:  我们在子类中重写的虚方法,不管在哪调用,都是使用的重写后的方法
前提:  用子类创建的对象调用虚方法,是用的重写后的方法
         用父类创建的对象调用虚方法,还是用的父类中原有的虚方法

例子:  class DiRen
    {
     public void AI()
        {
Move();
            Console.WriteLine("这是敌人公有的AI方法");
        }

public virtual void Move()
{
Console.WriteLine("这是公有的Move方法");
}
}

class Boss:DiRen
    {
        public void Attack()
        {
Move();
            Console.WriteLine("Boss正在进行攻击");
        }
public override void Move()
{
Console.WriteLine("这是子类中的Move方法");
}
    }
调用父类中的Move:
DiRen diren = new DiRen();
diren.AI();               这里显示的就是父类中Move方法
调用子类中的Move:
Boss boss = new Boss();
boss.Attack();            这里显示的就是子类中Move方法
 
 

三、隐藏方法  (一般很少使用)

1、介绍
    在子类中声明和父类中方法名一样的方法,而且没有使用虚方法的关键字
    父类中的方法就被隐藏了,可以在子类方法前加 new 关键字


2、区别
    虚方法是重写后是原来的方法不存在了,用子类创建的对象只能调用重写后的方法
    隐藏方法是把方法隐藏了,原来的方法还在
 
例子:  class DiRen
    {
     public void AI()
        {
Move();
            Console.WriteLine("这是敌人公有的AI方法");
        }

public  void Move()
{
Console.WriteLine("这是公有的Move方法");
}
}

class Boss:DiRen
    {
        public void Attack()
        {
Move();
            Console.WriteLine("Boss正在进行攻击");
        }
public int void Move()
{
Console.WriteLine("这是子类中的Move方法");
}
    }

调用父类中的Move:(调用隐藏方法)
DiRen diren = new Boss();
diren.AI();               这里显示的就是父类中Move方法
调用子类中的Move:
Boss boss = new Boss();
boss.Attack();            这里显示的就是子类中Move方法 
 
 

四、 this 和 base 关键字  (有没有都可以,有可以让IDE给出提示)

    this :可以通过 this 访问当前类中的字段、属性和方法
base : base 只能访问父类中的属性和方法


 

五、抽象类

    抽象类不能实例化,可以包含普通函数和抽象函数
抽象函数只有函数定义没有函数体,抽象函数本身也是虚拟的Virtual(虚函数)
关键字: abstract


例子:
abstract class Bird
    {
        private float speed;
        public void Eat();
        public abstract void Fly();
    }
如果有抽象函数,那么这个类也是抽象类

class Crow:Bird
    {
        public override void Fly()
        {
            Console.WriteLine("乌鸦在飞行");
        }
    }
如果一个子类继承了一个抽象类,就必须要重写该抽象方法!
  Bird crow = new Crow();
      crow.Fly();
虽然抽象类不能构造一个对象,但是可以声明一个对象在用子类去构造
  Bird crow    声明
  new Crow()   构造 


六、密封类和密封方法

1、介绍
    C#允许把类和方法声明为 sealed ,对于类,表示不能继承该类
                                对于方法,表示不能重写该方法

2、使用
    防止某些不需要继承或重写的类和方法导致代码混乱!

3、密封方法
    class DiRen
    {
public virtual void Move()
{
Console.WriteLine("这是公有的Move方法");
}
}
class Boss:DiRen
    {
    public sealed override void Move()
{
Console.WriteLine("这是子类中的Move方法");
}
    }
只能在重写的方法前加 sealed ,表示这个方法不能被重写了


七、子类的构造方法

1、在子类中调用父类的默认构造函数(无参)
class BassClass
    {
        public BassClass()
        {
            Console.WriteLine("bass class 无参的构造函数");
        }
    }
class DerivedClass:BassClass
    {
        public DerivedClass():base()
        {
            Console.WriteLine("这个是DerivedClass无参的构造函数");
        }
    }
关键字: :base()
如果构造一个对象,会先调用父类的,然后调用子类的构造函数

2、调用有参的构造函数
     class BassClass
    {
private int x;
        public BassClass(int x, int y)
        {
            this.x = x;
Console.WriteLine("x赋值完成");
        }
    }
class DerivedClass:BassClass
    {
private int y;
        public DerivedClass(int x, int y):base(x,y)
        {
this.y = y;
            Console.WriteLine("y赋值完成");
        }
    }
关键字: base( 类型 参数)
如果构造一个对象,会先调用父类的,然后调用子类的构造函数


八、修饰符

1、public和private
用于修饰类中的字段和方法
private 私有的        表示这个字段或方法只能在该类内部中访问
public  公有的        表示这个字段或方法可以通过声明的对象访问
 
public class...
   可以通过声明别的项目的类来访问该类
 
2、protected
    protected 应用于类型和内嵌类型的所有成员
          只有派生的类型能访问该项
  class BassClass
    {
        protected int z; 
}
  class DerivedClass:BassClass
    {
public DerivedClass()
{
base.z = z;
}
}
当没有继承时 protected 与 private 一样,
有继承时表示可以在子类中使用 protected 修饰的字段


3、static
    static 可以用来修饰字段和方法
       修饰字段和方法时叫做(静态字段)和(静态方法)
注意:
使用 static 修饰的成员只能通过类名访问
通过类构造出来的对象中不包含静态成员

使用:     可以通过 类名. 的形式直接访问

例子:
  class ClassXyz
    {
public static int z;
    }

  ClassXyz.z = 100;

注意:
你可以构造一个对象来访问类中的方法或字段,但字段的值或方法中的方法体不一样
但静态成员是唯一的,给它赋值或写上方法体后,所有对象使用都是一样的效果!
 
 

九、接口

    接口不能有构造函数,不能有字段,也不允许运算符重载
接口定义中不允许声明成员的修饰符,接口成员都是公有的
实现:定义了一个接口后,调用该接口叫实现
1、接口的名称一般用I开头


2、声明
     interface IFly
    {
        void Fly();
        void MethodA();
    }
接口中的函数类似于抽象类,只有函数定义没有函数体

3、派生的接口
     interface IA
    {
        void Method1();
    }

interface IB:IA
    {
        void Method2();
    }
 
class Bird :IB
    { 
    public void Method1()
{

}
    public void Method2()
{

}
}
当IB继承IA后,Bird继承IB就会有IB和IA中的方法


十、区别隐藏方法和虚方法

    Son a = new Son();
Father b = a;            相当于 Father b = new Son();
F表示隐藏方法
G表示虚方法
a.F();                   通过父类声明的对象,使用父类的隐藏方法
b.F();                   通过子类声明的对象,使用子类的隐藏方法
a.G();                   使用子类中的虚方法
b.G();                   使用子类中的虚方法

只要用子类构造了,不论父类对象还是子类对象调用都是使用重写后的虚方法!!
而隐藏方法是父类声明对象用父类中的方法,子类声明对象用子类中的方法!!



如果一个虚方法在子类中没有添加 override 关键字,就说明没有被重写
    而是被隐藏了!
原创粉丝点击