C#学习笔记(八)——定义类的成员
一、成员的定义
1、定义字段
- class Myclass
- {
- public int MyInt;
- }
可以使用readonly关键字,表示这个字段只能在执行构造函数的过程中赋值,或者由初始化语句赋值。
静态成员通过定义它的类来进行访问(MyClass.MyInt)
2、定义方法
- class Myclass
- {
- public int MyInt;
- public string GetString()
- {
- return "Here is a string!";
- }
- }
与override一样,也可以使用sealed指定在派生类中不能对这个方法作进一步的修改,。
使用extern可以在项目外部提供方法的实现代码。
3、定义属性
get和set区别:get是只读,set是只写。然后get块一定要有一个返回值,下面是示例。
- private int myInt;
- public int MyIntProp
- {
- get
- {
- return myInt;
- }
- set
- {
- }
- }
这样的话,由于myInt这个字段是私有的,外部成员时不能访问的,但是通过这个get和set就可以在外部修改了,但是前提是属性是共有的。
set是一个赋值的功能,但是set可以通过一系列操作来达到不同途径来设置方法。而且还可以这里加上出错的警告之类的。
然后就是get和set一样也可以在前面加上一系列的限定关键字。例如
- protected set
- {
- myInt = value;
- }
4、一个demo
创建一个MyClass.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Exercise
- {
- class MyClass
- {
- public readonly string Name;
- private int intVal;
- public int Val
- {
- get
- {
- return intVal;
- }
- set
- {
- if(value>=&&value<=)
- {
- intVal = value;
- }
- else
- {
- throw (new ArgumentOutOfRangeException("Val", value, "Val must be assigned a value between 0 and 10."));
- }
- }
- }
- public override string ToString()
- {
- return "Name:" + Name + "\nVal:" + Val;
- }
- public MyClass(string newName)
- {
- Name = newName;
- intVal=;
- }
- }
- }
在Main.cs中添加
- #region Using directives
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- #endregion
- namespace Exercise
- {
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Creating object myObj...");
- MyClass myobj = new MyClass("My Object");
- Console.WriteLine("myObj created.");
- for(int i=-;i<=;i++)
- {
- try
- {
- Console.WriteLine("\nAttemp to assign {0} to myObj.val...", i);
- myobj.Val = i;
- Console.WriteLine("Value {0} assigned to myObj.Val.", myobj.Val);
- }
- catch(Exception e)
- {
- Console.WriteLine("Exception {0} thrown.", e.GetType().FullName);
- Console.WriteLine("Message:\n\"{0}\"", e.Message);
- }
- }
- Console.WriteLine("\nOutputting myobj.Tostring()...");
- Console.WriteLine(myobj.ToString());
- Console.WriteLine("myobj.ToString() Output.");
- Console.ReadKey();
- }
- }
- }
二、类的高级议题
1、隐藏基类方法
(1)当从基类中继承一个非抽象的成员的时候,也就继承了其实现代码。
如果继承的成员时虚拟的,就可以用override重写这段代码。
无论继承的成员是不是虚拟的,都可以隐藏基类的代码。
- public class MyBaseClass
- {
- public void DoSometing()
- {
- //Base implementation
- }
- }
- public class MyDeriveClass:MyBaseClass
- {
- public void DoSometing()
- {
- //Derived class implementation, hides base implementation
- }
- }
尽管这段代码正常运行,但是还是会有一个waring,可以提醒我们是否有意隐藏这个成员。如果确实要隐藏这个成员,我们可以使用关键字new显式地表明意图。
- public class MyDeriveClass:MyBaseClass
- {
- new public void DoSometing()
- {
- //Derived class implementation, hides base implementation
- }
- }
(2)如果重写基类中的方法,派生类中的基类方法会被取代,即使是通过基类类型进行的,情况也是相同的。
- public class MyBaseClass
- {
- public virtual void DoSometing()
- {
- Console.WriteLine("FUCK");
- //Base implementation
- }
- }
- public class MyDeriveClass:MyBaseClass
- {
- public override void DoSometing()
- {
- Console.WriteLine("FUCK you!");
- //Derived class implementation, hides base implementation
- }
- }
- MyDeriveClass myObj = new MyDerivedClass();
- MyBaseClass myBaseObj;
- myBaseObj = myObj;
- myBaseObj.DoSomething();
明显,运算结果是FUCK you!
(3)还有就是可以使用隐藏基类的方法实现复写所能实现的功能。
2、调用重写或隐藏的基类方法
(1)重要性:
a、要对派生类的用户隐藏继承的公共成员,但仍能在类中访问其功能。
b、要给继承的虚拟成员添加实现代码,而不是地重写的新执行代码替换它。
(2)base关键字
使用base关键字可以使用基类中的隐藏的相应的方法。
- base.DoSomething();
(3)this关键字
a、可以在类内部使用,引用对象的实例。
b、把当前对象实例的引用传递给一个方法。
c、限定本地类型的成员。
- return this.someData
3、嵌套的类型定义
- class MyClass
- {
- public class myNestClass
- {
- public int nestedFlassField;
- }
- }
如果内部定义的类是共有的,那么就可以在外部使用,但是要加上限定名称,例如
- MyClass.myNestedClass myobj = new MyClass.myNestedClass();
如果嵌套的类声明为私有,或者声明为其他与执行该实例化的代码不兼容的访问级别就不能在外部访问。
三、接口的实现
1、定义方法
- interface IMyInterface
- {
- }
接口成员的定义与类相似,但是有一些重要的区别:
但是如果要隐藏继承了基接口的成员,可以用关键字new来定义他们。
在接口中定义的属性可以定义访问块get和set中的哪一个能够用于该属性~~~~~~~~~~~~
- interface IMyInterface
- {
- int MyInt(get;set;)
- }
2、在类中实现接口
实现接口的的类必须包含该接口所有成员的实现代码,且必须匹配指定的签名(包括匹配指定的get和set快),并且必须是公共的。
- interface IMyInterface
- {
- void DoSomething();
- void DoSomethingElse();
- }
- public class Myclass:IMyInterface
- {
- public void DoSomething()
- {
- }
- public void DoSomethingElse()
- {
- }
- }
可以使用virtual 或者abstract来实现接口成员。还可以在基类上实现接口。
- interface IMyInterface
- {
- void DoSomething();
- void DoSomethingElse();
- }
- public class Myclass:IMyInterface
- {
- public void DoSomething()
- {
- }
- }
- public class MyDerivedClass:Myclass,IMyInterface
- {
- public void DoSomethingElse()
- {
- }
- }
继承一个实现给定的基类,就意味着派生类隐式地支持这个接口。
当然如果基类中的方法定义为虚拟,那么派生类就可以替代这个方法,而不是隐藏它们。
(1)显示实现接口成员。
如果显示地实现接口成员,那么这个成员就是能通过接口来访问,不能通过该类来访问。
通过类访问:
- Myclass myobj = new Myclass();
- myobj.DoSomething();
通过接口访问:
- Myclass myobj = new Myclass();
- IMyinterface myInt = myobj;
- myInt.DoSomething();
(2)用非公共的可访问性添加属性存取器
简单的来说就是接口中如果定义了set而没有定义get,那么get就可以在类中添加,并且它的限制级更高。
四、部分类定义
就是使用部分类定义,把类的定义放在多个文件中。我们只需要在每个包含部分类定义的文件中对类使用partial关键字就好。
- public partical class MyClass
- {
- }
应用于部分类的接口也会应用于整个类..
部分类只能继承同一个基类,因为C#规定类只能继承一个基类.
五、部分方法定义
在一个部分声明,另一个部分实现(同C++)
- public partical class MyClass
- {
- partical void MyPartialMethod();
- }
- public partical class MyClass
- {
- partical void MypartialMethod()
- {
- }
- }
六、一个demo
//这是卡片类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace Ch10CardLib
- {
- public class Card
- {
- public Rank rank;
- public Suit suit;
- private Card()
- {
- throw new System.NotImplementedException();
- }
- public Card(Suit newSuit, Rank newRank)
- {
- suit = newSuit;
- rank = newRank;
- }
- public string Tostring()
- {
- return "The" + rank + "of" + suit + "s";
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- //这是一副牌
- namespace Ch10CardLib
- {
- public class Deck
- {
- private Card[] cards;
- public Deck()
- {
- cards = new Card[];
- for (int suitVal = ; suitVal < ; suitVal++)
- {
- for (int rankVal = ; rankVal < ; rankVal++)
- {
- cards[suitVal * + rankVal - ] = new Card((Suit)suitVal, (Rank)rankVal);
- }
- }
- }
- public Card Getcard(int cardNum)
- {
- if(cardNum>=&&cardNum<=)
- return cards[cardNum];
- else
- throw(new System.ArgumentOutOfRangeException("cardNum",cardNum,"Value must between 0 and 51"));
- }
- public void Shuffle()
- {
- Card[] newDeck = new Card[];
- bool[] assigned = new bool[];
- Random sourceGen = new Random();
- for(int i=;i<;i++)
- {
- int destCard=;
- bool foundCard=false;
- while(foundCard==false)
- {
- destCard = sourceGen.Next();
- if(assigned[destCard]==false)
- {
- foundCard = true;
- }
- }
- assigned[destCard]=true;
- newDeck[destCard]=cards[i];
- }
- newDeck.CopyTo(cards,);
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- //枚举
- namespace Ch10CardLib
- {
- public enum Rank
- {
- Ace = ,
- Deuce,
- Three,
- Four,
- Five,
- Six,
- Seven,
- Eight,
- Nine,
- Ten,
- Jack,
- Queen,
- King,
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace Ch10CardLib
- {
- public enum Suit
- {
- Club,
- Dimaond,
- Heart,
- Spade,
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Ch10CardLib;
- //主程序
- namespace Ch10CardClient
- {
- class Program
- {
- static void Main(string[] args)
- {
- Deck myDeck = new Deck();
- myDeck.Shuffle();
- for(int i=;i<;i++)
- {
- Card tempCard = myDeck.Getcard(i);
- Console.WriteLine(tempCard.Tostring());
- if (i != )
- Console.Write(", ");
- else
- Console.WriteLine();
- }
- Console.ReadKey();
- }
- }
- }
最后的最后,记住一点很好用的地方:
那就是用在类图处,可以直接使用工具栏提供好的类、枚举之类的工具快速创建,十分方便。
C#学习笔记(八)——定义类的成员的更多相关文章
- ES6学习笔记八:类与继承
一:Class ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类. 定义“类”的方法的时候,前面不需要加上function这个关键 ...
- go微服务框架kratos学习笔记八 (kratos的依赖注入)
目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...
- 【opencv学习笔记八】创建TrackBar轨迹条
createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...
- Java IO学习笔记八:Netty入门
作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- Go语言学习笔记八: 数组
Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...
随机推荐
- WPF 窗口在右下角出现,识别分辨率
直接上代码. Point brp = SystemParameters.WorkArea.BottomRight;//当前桌面右下角的位置
- 繁华模拟赛 Vicent坐电梯
/*n<=5000这样就不能用O(n)的转移了,而是要用O(1)的转移.注意我们每次的转移都来自一个连续的区间,而且我们是求和区间求和?前缀和!令sum[step][i]表示f[ste ...
- HDOJ 1848 Fibonacci again and again
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- js矩阵菜单或3D立体预览图片效果
js矩阵菜单或3D立体预览图片效果 下载地址: http://files.cnblogs.com/elves/js%E7%9F%A9%E9%98%B5%E8%8F%9C%E5%8D%95%E6%88% ...
- HDU 1018 Big Number (数学题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1018 解题报告:输入一个n,求n!有多少位. 首先任意一个数 x 的位数 = (int)log10(x ...
- Linux 日志文件utmp、wtmp、lastlog、messages
1.有关当前登录用户的信息记录在文件utmp中:==who命令 2.登录进入和退出纪录在文件wtmp中:==w命令 3.最后一次登录文件可以用lastlog命令察看: 4.messag ...
- HDOJ 2544
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- linux文件分割(将大的日志文件分割成小的)
linux文件分割(将大的日志文件分割成小的) linux下文件分割可以通过split命令来实现,可以指定按行数分割和安大小分割两种模式.Linux下文件合并可以通过cat命令来实现,非常简单. 在L ...
- linux shell 字符串操作(长度,查找,替换)详解
linux shell 字符串操作(长度,查找,替换)详解 在做shell批处理程序时候,经常会涉及到字符串相关操作.有很多命令语句,如:awk,sed都可以做字符串各种操作. 其实shell内置一系 ...
- cURL的几个经典实例
1.cURL请求的基本步骤: (1)初始化 (2)设置选项,包括URL (3)执行并获取HTML文档内容 (4)释放cURL句柄 <?php //1.初始化 $ch = curl_init(); ...