C#学习基础概念二十五问(2)

来源:互联网 发布:什么网游支持mac 编辑:程序博客网 时间:2024/05/21 21:46

10.this 关键字的含义?

答:

this 是一个保留字,仅限于构造函数和方法成员中使用

在类的构造函数中出现表示对正在构造的对象本身的引用,在类的方法中出现表示对调用该方法的对象的引用,在结构的构造上函数中出现表示对正在构造的结构的引用,在结构的方法中出现表示对调用该方法的结果的引用

this 保留字不能用于静态成员的实现里,因为这时对象或结构并未实例化

在 C# 系统中,this 实际上是一个常量,所以不能使用 this++ 这样的运算

this 保留字一般用于限定同名的隐藏成员、将对象本身做为参数、声明索引访问器、判断传入参数的对象是否为本身

示例:


 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4 
 5namespace Example10
 6C#学习基础概念二十五问(2){
 7    class Class1
 8C#学习基础概念二十五问(2)    {
 9        private double c;
10        private string value;
11 
12        public double C
13C#学习基础概念二十五问(2)        {
14            get
15C#学习基础概念二十五问(2)            {
16                return c;
17            }

18        }

19        public Class1(double c)
20C#学习基础概念二十五问(2)        {
21            //限定同名的隐藏成员
22            this.c = c;
23        }

24        public Class1(Class1 value)
25C#学习基础概念二十五问(2)        {
26            //用对象本身实例化自己没有意义
27            if (this != value)
28C#学习基础概念二十五问(2)            {
29                = value.C;
30            }

31        }

32        public override string ToString()
33C#学习基础概念二十五问(2)        {
34            //将对象本身做为参数
35            return string.Format("{0} Celsius {1} Fahrenheit"c, UnitTransClass.C2F(this));
36        }

37 
38        //由于好奇,在这做了一个效率测试,想看看到底哪种方式访问成员变量更快,结论:区别不大。。。
39        public string Test1()
40C#学习基础概念二十五问(2)        {
41            long vTickCount = Environment.TickCount;
42            for (int = 0< 10000000i++)
43                this.value = i.ToString();
44            return string.Format("Have this.: {0} MSEL"Environment.TickCount - vTickCount);
45        }

46        public string Test2()
47C#学习基础概念二十五问(2)        {
48            long vTickCount = Environment.TickCount;
49            for (int = 0< 10000000i++)
50                value = i.ToString();
51            return string.Format("Don't have this.: {0} MSEL"Environment.TickCount - vTickCount);
52        }

53    }

54    class UnitTransClass
55C#学习基础概念二十五问(2)    {
56        public static double C2F(Class1 value)
57C#学习基础概念二十五问(2)        {
58            //摄氏到华氏的转换公式
59            return 1.8 * value.C + 32;
60        }

61    }

62    class Program
63C#学习基础概念二十五问(2)    {
64        static void Main(string[] args)
65C#学习基础概念二十五问(2)        {
66            Class1 tmpObj = new Class1(37.5);
67 
68            Console.WriteLine(tmpObj);
69 
70            Console.WriteLine(tmpObj.Test1());
71            Console.WriteLine(tmpObj.Test2());
72 
73            Console.ReadLine();
74        }

75    }

76}

77结果:
7837.5 Celsius = 99.5 Fahrenheit
79Have this.: 4375 MSEL
80Don'have this.: 4406 MSEL 
81
82
复制代码

11.可以使用抽象函数重写基类中的虚函数吗?

答:

可以,但需使用 new 修饰符显式声明,表示隐藏了基类中该函数的实现

示例:

 

 1   class BaseClass
 2C#学习基础概念二十五问(2)    {
 3        public virtual void F()
 4C#学习基础概念二十五问(2)        {
 5            Console.WriteLine("BaseClass.F");
 6        }

 7    }

 8    abstract class  DeriveClass BaseClass
 9C#学习基础概念二十五问(2)    {
10        public new abstract void F();
11    }

12
复制代码

12.密封类可以有虚函数吗?

答:

可以,基类中的虚函数将隐式的转化为非虚函数,但密封类本身不能再增加新的虚函数

示例:

 

 

 1    class BaseClass
 2C#学习基础概念二十五问(2)    {
 3        public virtual void F()
 4C#学习基础概念二十五问(2)        {
 5            Console.WriteLine("BaseClass.F");
 6        }

 7    }

 8    sealed class DeriveClass BaseClass
 9C#学习基础概念二十五问(2)    {
10        //基类中的虚函数F被隐式的转化为非虚函数
11 
12        //密封类中不能再声明新的虚函数G
13        //public virtual void G()
14        //{
15        //    Console.WriteLine("DeriveClass.G");
16        //}
17    }
复制代码

13.如果基类中的虚属性只有一个属性访问器,那么继承类重写该属性后可以有几个属性访问器?如果基类中有 get 和 set两个呢?

答:

如果基类中的虚属性只有一个属性访问器,那么继承类重写该属性后也应只有一个。如果基类中有 get 和 set两个属性访问器,那么继承类中可以只有一个也可以同时有两个属性访问器


14.abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?

答:

abstract 修饰符不可以和 static、virtual 和 override 修饰符一起使用


15.接口可以包含哪些成员?

答:

接口可以包含属性、方法、索引指示器和事件,但不能包含常量、域、操作符、构造函数和析构函数,而且也不能包含任何静态成员

 

16.类和结构的区别?

答:
类:

类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存

类有构造和析构函数

类可以继承和被继承

结构:

结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。

结构没有构造函数,但可以添加。结构没有析构函数

结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口

 

示例:

根据以上比较,我们可以得出一些轻量级的对象最好使用结构,但数据量大或有复杂处理逻辑对象最好使用类。

如:Geoemtry(GIS 里的一个概论,在 OGC 标准里有定义) 最好使用类,而 Geometry中点的成员最好使用结构


  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4 
  5namespace Example16
  6C#学习基础概念二十五问(2){
  7    interface IPoint
  8C#学习基础概念二十五问(2)    {
  9        double X
 10C#学习基础概念二十五问(2)        {
 11            get;
 12            set;
 13        }

 14        double Y
 15C#学习基础概念二十五问(2)        {
 16            get;
 17            set;
 18        }

 19        double Z
 20C#学习基础概念二十五问(2)        {
 21            get;
 22            set;
 23        }

 24    }

 25    //结构也可以从接口继承
 26    struct Point: IPoint
 27C#学习基础概念二十五问(2)    {
 28        private double x, y, z;
 29        //结构也可以增加构造函数
 30        public Point(double X, double Y, double Z)
 31C#学习基础概念二十五问(2)        {
 32            this.x = X;
 33            this.y = Y;
 34            this.z = Z;
 35        }

 36        public double X
 37C#学习基础概念二十五问(2)        {
 38C#学习基础概念二十五问(2)            get return x; }
 39C#学习基础概念二十五问(2)            set = value; }
 40        }

 41        public double Y
 42C#学习基础概念二十五问(2)        {
 43C#学习基础概念二十五问(2)            get return x; }
 44C#学习基础概念二十五问(2)            set = value; }
 45        }

 46        public double Z
 47C#学习基础概念二十五问(2)        {
 48C#学习基础概念二十五问(2)            get return x; }
 49C#学习基础概念二十五问(2)            set = value; }
 50        }

 51    }

 52    //在此简化了点状Geometry的设计,实际产品中还包含Project(坐标变换)等复杂操作
 53    class PointGeometry
 54C#学习基础概念二十五问(2)    {
 55        private Point value;
 56        
 57        public PointGeometry(double X, double Y, double Z)
 58C#学习基础概念二十五问(2)        {
 59            value = new Point(X, Y, Z);
 60        }

 61        public PointGeometry(Point value)
 62C#学习基础概念二十五问(2)        {
 63            //结构的赋值将分配新的内存
 64            this.value = value;
 65        }

 66        public double X
 67C#学习基础概念二十五问(2)        {
 68C#学习基础概念二十五问(2)            get return value.X; }
 69C#学习基础概念二十五问(2)            set this.value.X = value; }
 70        }

 71        public double Y
 72C#学习基础概念二十五问(2)        {
 73C#学习基础概念二十五问(2)            get return value.Y; }
 74C#学习基础概念二十五问(2)            set this.value.Y = value; }
 75        }

 76        public double Z
 77C#学习基础概念二十五问(2)       {
 78C#学习基础概念二十五问(2)            get return value.Z; }
 79C#学习基础概念二十五问(2)            set this.value.Z = value; }
 80        }

 81        public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
 82C#学习基础概念二十五问(2)        {
 83            return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
 84        }

 85        public override string ToString()
 86C#学习基础概念二十五问(2)        {
 87            return string.Format("X: {0}, Y: {1}, Z: {2}"value.X, value.Y, value.Z);
 88        }

 89    }

 90    class Program
 91C#学习基础概念二十五问(2)    {
 92        static void Main(string[] args)
 93C#学习基础概念二十五问(2)        {
 94            Point tmpPoint = new Point(123);
 95 
 96            PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
 97            PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
 98            tmpPG2.X = 4;
 99            tmpPG2.Y = 5;
100            tmpPG2.Z = 6;
101 
102            //由于结构是值类型,tmpPG1 和 tmpPG2 的坐标并不一样
103            Console.WriteLine(tmpPG1);
104            Console.WriteLine(tmpPG2);
105 
106            //由于类是引用类型,对tmpPG1坐标修改后影响到了tmpPG3
107            PointGeometry tmpPG3 = tmpPG1;
108            tmpPG1.X = 7;
109            tmpPG1.Y = 8;
110            tmpPG1.Z = 9;
111            Console.WriteLine(tmpPG1);
112            Console.WriteLine(tmpPG3);
113 
114            Console.ReadLine();
115        }

116    }

117}

118结果:
119X: 1Y: 2Z: 3
120X: 4Y: 5Z: 6
121X: 7Y: 8Z: 9
122X: 7Y: 8Z: 9 
123
124
复制代码

17.接口的多继承会带来哪些问题?

答:

C# 中的接口与类不同,可以使用多继承,即一个子接口可以有多个父接口。但如果两个父成员具有同名的成员,就产生了二义性(这也正是C# 中类取消了多继承的原因之一),这时在实现时最好使用显式的声明

示例:

 

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4 
 5namespace Example17
 6C#学习基础概念二十五问(2){
 7    class Program
 8C#学习基础概念二十五问(2)    {
 9        //一个完整的接口声明示例
10        interface IExample
11C#学习基础概念二十五问(2)        {
12            //属性
13            string P
14C#学习基础概念二十五问(2)            {
15                get;
16                set;
17            }

18            //方法
19            string F(int Value);
20            //事件
21            event EventHandler E;
22            //索引指示器
23            string this[int Index]
24C#学习基础概念二十五问(2)            {
25                get;
26                set;
27            }

28        }

29        interface IA
30C#学习基础概念二十五问(2)        {
31C#学习基础概念二十五问(2)            int Count getset;}
32        }

33        interface IB
34C#学习基础概念二十五问(2)        {
35            int Count();
36        }

37        //IC接口从IA和IB多重继承
38        interface IC IA, IB
39C#学习基础概念二十五问(2)        {
40        }

41        class IC
42C#学习基础概念二十五问(2)        {
43            private int count = 100;
44            //显式声明实现IA接口中的Count属性
45            int IA.Count
46C#学习基础概念二十五问(2)            {
47C#学习基础概念二十五问(2)                get return 100}
48C#学习基础概念二十五问(2)                set count = value; }
49            }

50            //显式声明实现IB接口中的Count方法
51            int IB.Count()
52C#学习基础概念二十五问(2)            {
53                return count * count;
54            }

55        }

56        static void Main(string[] args)
57C#学习基础概念二十五问(2)        {
58            tmpObj = new C();
59 
60            //调用时也要显式转换
61            Console.WriteLine("Count property: {0}"((IA)tmpObj).Count);
62            Console.WriteLine("Count function: {0}"((IB)tmpObj).Count());
63 
64            Console.ReadLine();
65        }

66    }

67}

68结果:
69Count property: 100
70Count function: 10000 
71
72
73
74
复制代码

18.抽象类和接口的区别?

答:

抽象类(abstract class)可以包含功能定义和实现,接口(interface)只能包含功能定义

抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定,因此反映的是事物的外部特性

分析对象,提炼内部共性形成抽象类,用以表示对象本质,即“是什么”

为外部提供调用或功能需要扩充时优先使用接口


0 0
原创粉丝点击