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>=0&&value<=10){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=0;}} }
在Main.cs中添加
#region Using directivesusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;#endregionnamespace 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=-1;i<=0;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[52];for (int suitVal = 0; suitVal < 4; suitVal++){for (int rankVal = 1; rankVal < 14; rankVal++){cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal, (Rank)rankVal);}}}public Card Getcard(int cardNum){if(cardNum>=0&&cardNum<=51)return cards[cardNum];elsethrow(new System.ArgumentOutOfRangeException("cardNum",cardNum,"Value must between 0 and 51"));}public void Shuffle(){Card[] newDeck = new Card[52];bool[] assigned = new bool[52];Random sourceGen = new Random();for(int i=0;i<52;i++){int destCard=0;bool foundCard=false;while(foundCard==false){destCard = sourceGen.Next(52);if(assigned[destCard]==false){foundCard = true;}}assigned[destCard]=true;newDeck[destCard]=cards[i];}newDeck.CopyTo(cards,0);}} }
using System; using System.Collections.Generic; using System.Linq; using System.Text;//枚举
namespace Ch10CardLib {public enum Rank{Ace = 1,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=0;i<52;i++){Card tempCard = myDeck.Getcard(i);Console.WriteLine(tempCard.Tostring());if (i != 51)Console.Write(", ");elseConsole.WriteLine();}Console.ReadKey();}} }
最后的最后,记住一点很好用的地方:
那就是用在类图处,可以直接使用工具栏提供好的类、枚举之类的工具快速创建,十分方便。
C#学习笔记(八)——定义类的成员相关推荐
- ReactJS学习笔记八:动画
ReactJS学习笔记八:动画 分类: react学习笔记 javascript2015-07-06 20:27 321人阅读 评论(0) 收藏 举报 react动画 目录(?)[+] 这里只讨论Re ...
- JVM学习笔记(Ⅰ):Class类文件结构解析(带你读懂Java字节码,这一篇就够了)
JVM学习笔记(Ⅰ):Class类文件结构解析,带你读懂Java字节码 前言:本文属于博主个人的学习笔记,博主也是小白.如果有不对的地方希望各位帮忙指出.本文主要还是我的学习总结,因为网上的一些知识分 ...
- 黑马程序员_java自学学习笔记(八)----网络编程
黑马程序员_java自学学习笔记(八)----网络编程 android培训. java培训.期待与您交流! 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无 ...
- 【opencv学习笔记八】创建TrackBar轨迹条
createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...
- python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...
- Kotlin学习笔记12——数据类和密封类
Kotlin学习笔记12--数据类和密封类 前言 数据类 在类体中声明的属性 复制 componentN 解构声明 密封类 尾巴 前言 上一篇,我们学习了Kotlin中的拓展,今天继续来学习Kotli ...
- ZooKeeper学习笔记(八):ZooKeeper集群写数据原理
写数据原理 写流程直接请求发送给Leader节点 这里假设集群中有三个zookeeper服务端 ACK (Acknowledge character)即是确认字符,在数据通信中,接收站发给发送站的一种 ...
- MongoDB 学习笔记八 复制、分片、备份与恢复、监控
MongoDB 学习笔记八 复制.分片.备份与恢复.监控 MongoDB复制(副本集) 什么是复制? MongoDB 复制原理 MongoDB 副本集设置 副本集添加成员 MongoDB 分片 分片 ...
- python3第三方库手册_python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑...
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...
- Polyworks脚本开发学习笔记(八)-组合运用命令批量改名
Polyworks脚本开发学习笔记(八)-组合运用命令批量改名 需求解析 以下是使用包边比较点创建的一组包边点(即Gap点)和曲面点-包边点(即Flush点),这种命名方式不太常规,改为Gap和Flu ...
最新文章
- 【组队学习】【24期】集成学习(中)
- linux nohup 英文全称 no hang up(
- xen虚拟化实战系列(一)之xen虚拟化环境安装
- petapoco mysql_PetaPocoEfCoreMvc[持续更新]欢迎在github上star
- vba 提取 json某个值_Excel中提取不重复值的方法汇总(5种基础+VBA+1个自定义函数)...
- [sol]250OJ 1~10
- 实验 4 操作、输出值和数据表实验报告--软件功能测试与性能测试实验
- 学习 Spring Boot:(二十九)Spring Boot Junit 单元测试
- linux 文件名带特殊符号,Linux删除含有特殊符号文件名的文件
- C++基础16-类和对象之联编,重写,虚析构
- JAVA对时间的几个处理小方法
- 动态规划求解疯狂的采药问题(洛谷P1616题题解,Java语言描述)
- JavaScript 之call , apply 和prototype 介绍
- 西门子840d备份到u盘_840dsl 启动服务U盘制作和CF卡数据备份回装
- React.js 菜鸟入门
- EtherCAT运动控制器的PLC编程(一) 直线插补
- Macbook pro 2015款 换完硬盘bootcamp 尝试访问启动磁盘设置时出错解决方法
- vue脚手架 使用npm run dev 遇到的错误问题
- 将Excel中的图片链接替换为图片
- vscode遇到无法访问此网站问题的两种解决方法