C#中类Class— 03

一、类(class)

1、定义一个类中包含

  • 成员变量,也称作字段
  • 成员函数,也称作方法

【注意】:在同一个命名空间下定义的类时,相互调用时不需要引入命名空间。若是在不同的命名空间下,则在使用之前需要引入命名空间。

在一个类中调用另一个类中的变量或函数时,需要先为被调用的类创建对象,并将该对象初始化。然后再通过该对象来调用对应的变量或函数。

// 自定义的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBKe
{
    class MyClass
    {
        public string name;
        public int age;
        public void Show()
        {
            Console.WriteLine("Just a test");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CZBKe
{
        
    class Program 
    {
        
        static void Main(string[] args)
        {
            // 创建类的对象,并用 new 进行初始化
            MyClass myst = new MyClass();
            myst.age = 20;
            myst.Show();

            Console.ReadKey();
        }
        
    }
}

2、类的构造函数

// 自定义的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TheUseClass
{
    class NewCreateClass
    {
        // 一般将数据成员(即字段)设置为私有
        private float x, y, z;

        // 为字段提供方法来设置字段的值
        public void SetX(float x)
        {
            // 通过this 表示访问的是类的字段或方法
            this.x = x;
        }
        public void SetY(float y)
        {
            this.y = y;
        }
        public void SetZ(float z)
        {
            this.z = z;
        }

        public float Dis()
        {
            return (float)Math.Sqrt(x * x + y * y + z * z);
        }

    }

    class VectorTest
    {
        private float x, y, z;

       
        public VectorTest(float x,float y,float z) // 构造函数
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TheUseClass
{
    class Program
    {
        static void Main(string[] args)
        {
            NewCreateClass myclass = new NewCreateClass();
            // 通过公有的函数来设置字段的值
            myclass.SetX(10);
            myclass.SetY(20);
            myclass.SetZ(30);

            Console.WriteLine(myclass.Dis());

            // 调用构造函数
            VectorTest vt = new VectorTest(1,2,3);

            Console.ReadKey();

        }
    }
}

二、继承

继承有两种:实现继承、接口继承。【注】 C# 不支持实现多重继承

1、两种继承的定义

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

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

(1)实现继承:继承父类的子类

// 基类
using System;

namespace ATotal
{
    class BaseClass
    {
        public float Speed { get; set; }
        public float Move { get; set; }
        public string Area { get; set; }

        public void AI()
        {
            Console.WriteLine("调用基类 AI");
        }
    }

}

 

// 继承基类的子类
using System;

namespace ATotal
{
    class DeriveClass:BaseClass
    {
        public void Test()
        {
            Console.WriteLine("This is derive class");
        }
    }
}

 

// 主函数所在的类
using System;

namespace ATotal
{
    class Program
    {
        static void Main(string[] args)
        {
            DeriveClass deriveClass = new DeriveClass();
            deriveClass.AI();
            deriveClass.Test();

            Console.ReadKey();
            
        }
    }
}

(2)、父类声明的对象可以使用子类去构造;但是子类声明的对象不可以使用父类去构造。因为子类比父类范围更大。

BaseClass theBase;  // 父类声明的对象
theBase = new DeriveClass(); // 用子类来进行构造

(3)、一个对象是什么类型的,主要是看它通过什么构造的,如:

BaseClass theBase = new BaseClass();
DeriveClass derive = (DeriveClass)theBase;

2、派生类的构造函数

(1)、在子类中掉用父类的无参构造函数。

【注】 此时可以省略掉  : base ()   

// 基类
using System;

namespace ATotal
{
    class BaseClass
    {
        public BaseClass()
        {
            Console.WriteLine("This is Base Class");
        }
    }
}

// 派生类
using System;

namespace ATotal
{
    class DeriveClass:BaseClass
    { 
    // 会先默认调用父类中的无参构造函数,再调用子类中的构造函数
        public DeriveClass():base()  
        {
            Console.WriteLine("This is Derive class");
        }
       
    }
}

//主函数的类
using System;

namespace ATotal
{
    class Program
    {
        static void Main(string[] args)
        {
            // 在此会默认调用主函数中的无参构造函数
            DeriveClass derive1 = new DeriveClass();

            Console.ReadKey();            
        }
    }
}

(2)、调用基类有参的构造函数

// 基类
using System;

namespace ATotal
{
    class BaseClass
    {
        private float x; 
        public BaseClass(float x)
        {
            this.x = x;
            Console.WriteLine("This is Base Class.  x = "+this.x);
        }
    }
}

// 派生类
using System;

namespace ATotal
{
    class DeriveClass:BaseClass
    {
        private float y;
        public DeriveClass(float x ,float y):base( x)
        {
            this.y = y;
            Console.WriteLine("This is Derive class y = "+this.y);
        }
       
    }
}

// 主函数所在类
using System;

namespace ATotal
{
    class Program
    {
        static void Main(string[] args)
        {
            // 在此会默认调用主函数中的无参构造函数
            DeriveClass derive1 = new DeriveClass(10,20);

            Console.ReadKey();            
        }
    }
}

运行结果如下所示

 

 


三、虚函数、base、this 关键字

1、有 virtual 关键字修饰的函数,表示该方法可以被继承的类重写。

2、有 override 关键字修饰时,表示重写了一个父类的方法。

public class Student
{
   public virtual void MyFunc()  //virtual:该方法可以被继承的类重写
   {
      Console.WriteLine(1);
    }
}

public class MyStudent:Student
{
    public override void MyFunc()  //override:重写了一个父类的方法。
    {
        Console.WriteLine(2);
    }
}

【注】:对于子类继承父类,并重写父类中的虚方法。父类创建的对象会调用父类中的方法,子类创建的对象会调用子类中的方法。

3、如果父类和派生类中都声明了同一个方法,但该方法在父类中没有用 virtual 关键字,在子类中没有用 override 关键字,则派生类就会隐藏基类中的该方法。如果用子类声明的对象,则会调用子类中的该方法;如果使用父类声明的对象,则会调用父类中的该方法。

4、base 与 this 关键字。当父类与子类具有相同的成员时,通过base关键字来调用父类的成员;通过 this 关键字来调用当前类的成员(有没有this都可以访问)。如下所示。

public class Student{
   public virtual void MyFunc(){
      Console.WriteLine(1);
   }
}

public class MyStudent:Student{
   public override void MyFunc(){
     Console.WriteLine(2);
   }
   // 通过base关键字调用父类的函数成员。
   public void f1(){
   base.MyFunc();
   }
   // 通过this关键字调用子类的函数成员。
   public void f2(){
   this.MyFunc();
   }
}

【注】:当方法的参数跟字段重名时,使用this 可以表明访问的是类中的字段。

class Test02
{
    private float x;
    public Test02(float x)
    {
        this.x = x;
    }
}

四、抽象类

1、定义

  

2、当子类一定会去重写父类的方法时,可以将父类中的方法定义为抽象类。如果一个类中包含有抽象函数,则该类一定是抽象类。因为抽象类是不完整的,所以抽象类不能用于构造函数对象。

// 抽象的基类
using System;

namespace ATotal
{
    abstract class BaseClass
    {
        private float speed;
        public void Eat()
        {

        }
        abstract public void Fly();
    }
}
// 继承抽象类的一个子类
using System;

namespace ATotal
{
    class DeriveClass:BaseClass
    { // 继承一个抽象类的时候必须要去实现抽象方法,因为父类未进行实现
        public override void Fly()
        {
            Console.WriteLine("This is a class derived from a abstract base class");
        }
    }
}
using System;

namespace ATotal
{
    class Program
    {
        static void Main(string[] args)
        {
            DeriveClass derive1 = new DeriveClass();
            derive1.Fly();

            Console.ReadKey();
            
        }
    }
}

五、密封类

密封类与密封方法

  • 密封类可以用于任何类,将 sealed 放在类前表示该类为密封类,不能被继承。
  • 密封方法只能用于重写的方法上(override 修饰的方法上),表示该方法不能再被重写了。
// 密封类
sealed class MyClass
{

}
// 密封方法
// 父类中的方法
public virtual void Eat()
{

}

// 子类中的方法
sealed public override void Eat()
{

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值