C#基础——类与对象

using System;
namespace HelloCar  // namespace
{
	class Factory  // defination a car factory
	{
		public int MileCount=0;
		public static int CarCount=0;
		public Factory()
		{
			CarCount++;
		}
		public void Run(int n)
		{
			MileCount+=n;
		}
	}
	class myWorld
	{
		static void Main()
		{
			Factory car1=new Factory();
			Factory car2=new Factory();
			car1.Run(5);
			car2.Run(10);
			Console.WriteLine("number of cars={}, total mile={}km",Factory.CarCount,car1.MileCount+car2.MileCount);
		}
	}
}

类的声明:修饰符 class 类名
类的成员:

  1. 数据成员:修饰符 类型 变量;
  2. 构造函数:修饰符 类名();
  3. 函数:修饰符 函数名();
  4. 内嵌类型:修饰符 内嵌类型 类型名{}

修饰符:

访问性修饰符 应用于 说明
public 所有类型和成员(析构函数除外) 不限制对该类或成员的访问
private 所有内嵌类型和成员 不能在定义此成员的类之外访问它,派生类也不行
protected 所有内嵌类型和成员 只能从所在类和派生子类中访问
internal 所有内嵌类型和成员 此成员只在当前程序集中可见
protected internal 所有内嵌类型和成员 只在当前程序集的类和派生子类访问

注:非内嵌类型不能是私有的
没有添加访问修饰符的所有成员和内嵌类型都是private的
没有添加访问修饰符的所有非内嵌类型都是internal的
其他修饰符:

修饰符 应用于 说明
new 内嵌类型和所有成员 新成员隐藏父类中名称相同的成员
static 所有成员(析构函数除外) 静态成员属于类,不属于对象
virtual 类和函数成员 虚成员可由派生类重写
abstract 类和函数成员 抽象成员定义类型签名,不提供代码
override 函数成员 重写了父类的虚成员或抽象成员
sealed 类,方法和属性 sealed密封类不能继承
extern 仅用于静态方法 extern成员在外部用另一语言实现,可修饰析构函数

静态类不构造任何对象,也不用来定义对象变量

数据成员

<Modifier> type var_name;
<Modifier> type var_name = initial_value;

数据成员有默认值;bool->false;数值->0;string->null;char->’\0’;引用->null
带有static静态类的字段,属于类所有,而不属于对象所有
可访问性约束:字段的访问性不应高于类的可访问性,下面的程序会报错

internal class A
{}
public C
{ public A a=new A();
}

改为public class A即可

函数成员

方法

<Modifier> reture_type name(tpye para1,type para2,...)

方法的签名:return_type name(type para1,…)
用签名可以区分两个不同的方法

double r=circleArea(9);
Console.WriteLine(r);
Car car1=new car();
car1.Run();

方法的调用有三种方式,第一种是直接调用;第二种是静态方法的调用,用类名.方法名;第三种是实例化方法的调用,用对象名.方法
方法的形参和实参
方法的参数有:值类型、引用型参数、输出型参数、数组型参数
值参数调用前后不改变原有值
值参数

 static void Swap(int a1, int b1)
        {
            int t = a1;
            a1 = b1;
            b1 = t;
        }
        static void Main(string[] args)
        {
            int a = 6, b = 4;
            Swap(a, b);
            Console.WriteLine("a={0},b={1}",a,b);
            Console.ReadKey();
        }

返回值:a=6,b=4
引用参数

static void Swap(ref int a1, ref int b1)
        {
            int t = a1;
            a1 = b1;
            b1 = t;
        }
        static void Main(string[] args)
        {
            int a = 6, b = 4;
            Swap(ref a, ref b);
            Console.WriteLine("a={0},b={1}",a,b);
            Console.ReadKey();
        }

返回值:a=4,b=6
输出参数

static void Swap(int a, int b, out int a1, out int b1)
        {
            a1 = a; b1 = b;
            int t = a1;
            a1 = b1;
            b1 = t;
        }
        static void Main(string[] args)
        {
            int a = 6, b = 4;
            Swap(a, b,out a,out b);
            Console.WriteLine("a={0},b={1}",a,b);
            Console.ReadKey();
        }

返回值:a=4,b=6
数组参数
数组参数是引用类型,只能允许一个一维数组参数放在参数列表的最后

static void Swap(params int[] a)
        {
            int t = a[0];
            a[0] = a[1];
            a[1] = t;
        }
        static void Main(string[] args)
        {
            int[] a = { 6, 4 };
            Swap(a);
            Console.WriteLine("a={0},b={1}",a[0],a[1]);
            Console.ReadKey();
        }

返回值:a=4,b=6

属性

属性用来封装字段,set用来设置字段,只包含set的属性是只写属性;get用来读取字段,只包含get的属性是只读属性;两个都包含的属性是读写属性
使用set设置字段,要首先判断字段的value的正确性

class Student
        {
            public string name;
            private int age;
            public int Age
            {
                set
                {
                    if (value < 0)
                        Console.WriteLine("年龄不能小于0!");
                    else age = value;
                }
                get
                { return age; }
            }
        }
        static void Main(string[] args)
        {
            Student s = new Student();
            s.Age = -20;
            s.Age = 30;
            Console.WriteLine(s.Age);
            Console.ReadKey();
        }

属性相当于封装了一个字段value和两个方法set、get
自动属性:当属性只用来读或赋值时,可以用{set;get;}的自动属性

索引器

 class Books
    {
        private string[] Title = new string[100];
        private string[] Author = new string[100];
        public string this[int i,string index]
        {
            set
            {
                if(index=="Author")
                {
                    Author[i] = value;
                }
                else if(index=="Title")
                {
                    Title[i] = value;
                }
            }
            get
            {
                if (index == "Author") return Author[i];
                if (index == "Title") return Title[i];
                return "Unknown";
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Books books = new Books();
            books[0, "Title"] = "征服美丽少女";books[0, "Author"] = "dsh";
            books[1, "Title"] = "打败英俊少男"; books[1, "Author"] = "wtt";
            for(int i=0;i<2;i++)
            {
                Console.WriteLine(books[i, "Title"] + " " + books[i, "Author"]);
                Console.ReadKey();
            }
        }
    }

索引器类似Python中的字典,通过关键字进行索引
索引器定义中,索引器名称必须是this,之后用[]来引导

运算符重载

class Complex
    {
        double r, i;
        public Complex(double r0,double i0)
        {
            r = r0;i = i0;
        }
        public static Complex operator + (Complex c1,Complex c2)
        {
            Complex c = new Complex(0, 0);
            c.r = c1.r + c2.r;
            c.i = c1.i + c2.i;
            return c;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Complex c1 = new Complex(2, 1);
            Complex c2 = new Complex(4, 3);
            Complex c3 = c1 + c2;
        }
    }

重载运算符,修饰符必须是public static,要重载的运算符前有operator

构造函数

静态构造函数
在创建第一个实例或引用任何静态成员之前,系统自动调用静态构造函数来初始化类的静态字段,之后再也不调用。用户无法直接调用静态构造函数,也不可继承

class C
{  public int a;
	public static int s;
	static C()
	{s=123;}
}
class Program
{  static void Main()
	{  Console.WriteLine(C.s);
	}
}

实例构造函数

class C
{  public int a;
	public static int s;
	static C()
	{s=123;}
	public C(int a)
	{  this.a=a; }
	public C()
	{  a=456; }
}
class Program
{  static void Main()
	{  
		C c;
		c=new C(789);
		Console.WriteLine(c.a);
	}
}

可以定义多个实例构造函数,他们拥有不同的签名
当形参与字段同名时,用this关键字区分字段

析构函数

析构函数在对象脱离作用域时自动执行,定义语法如下

~class_name()
{}

不能带任何参数,也没有返回值,不能重载,不能继承,无法调用
一般不需要自己定义析构函数,除非类中打开了非托管资源

发布了7 篇原创文章 · 获赞 2 · 访问量 644

猜你喜欢

转载自blog.csdn.net/qq_41450779/article/details/89988003