又是新的一周,小白又来学习C#了,今天要学的内容是C#的面向对象的特性-类与继承,我们直接看题,然后说明其中的知识点:

编写一个C#程序,定义:

  1. 一个表示人的类Person,包括字段“姓名”“性别”,方法“获得性别”,属性“年龄”,限定“年龄”的取值范围为0~120;
  2. 一个表示学生的类Student,继承自Person,包括字段“学号”“班号”;方法“获得学号”“获得班号”。

这里我先给出我在课堂上写的代码(没有写主函数,可自行编写测试),然后逐点说明一下其中的注意点:

using System;namespace ConsoleApp4
{class Person{private string name;private string sex;private int age;public Person(string name,string sex,int age){this.name = name;this.sex = sex;this.age = age;}public string getsex(){return sex;}public int Age{get{return age;}set{if (Age < 0 && Age > 120)Console.WriteLine("Age error.");}}}class Student : Person{private int number;private int cnumber;public Student(string name,string sex,int age,int number,int cnumber):base(name,sex,age){this.number = number;this.cnumber = cnumber;}public int get_number(){return number;}public int get_cnumber(){return cnumber;}}
}

下面开始说明:

首先,第3行的ConsoleApp4这个名字空间其实就是创建的工程名,这里在创建的时候自己设置的,无需多言

其次就是这句:

class Person

这个是这个类的名称,而这里这个名称是和我创建的.cs文件名(C#的代码文件)是一样的,看一下旁边的解决方案的截图,

好的接下来就是C#的核心知识点,第一部分:类,字段和方法

首先,C#是面向对象的语言,面向对象语言的一个重要特点就是具有“封装性”,而类就是实现封装性的重要手段,C#中通过将事物表达成类(class),每个类又通过字段(filed)和方法(method)来表达事物的状态和行为。

//定义类class 类名{...
}

类中包含两种最基本的元素:字段和方法其中字段(filed)是表示事物的状态,又称字段变量,成员变量和域(没错,对应C++中的成员变量),而方法(method)就是表示类的动态行为,即类所具有的功能和操作。

我们可以看出来,字段和方法的定义方法与C++中的有些许差异,我们看下面这段更简洁的代码,我们同样用Person类来说明:

class Person
{public string name;public int age;public void SayHello(){Console.WriteLine("Hello!My name is " + name);}public string GetInfo(){return "Name:" + name + ",Age:" + age;}
}
  • 定义字段和方法的形式:

//定义字段
修饰符 返回值类型 字段名;//定义方法
修饰符 返回值类型 方法名(形参列表){}
  • 构造和析构方法

有过其他语言基础的应该很容易理解,下面是构造方法(constructor):主要作用是完成对象的初始化工作,但是注意以下两点:

  1. 构造方法的方法名与类名相同
  2. 构造方法没有返回类型,也不能写void

形如:修饰符 构造方法名(即类名) (形参列表){}

public Person(string n,int a){name = n;age = a;
}

这里我们用自定义的形参来初始化字段,如果我们没有定义任何构造方法的话,系统就会自动产生一个,形如

public Person(){}

有了构造方法,那就一定有析构方法(Destructor),这一点和C++也是相对应的,只需要在构造函数前加一个"~"我们继续用Person类来举例:

~Person(){}

但其实由于C#会自动进行对象的释放,所以我们一般不用显式的定义析构方法。

  • 对象的创建和使用

首先C#中的构造方法不能显式地直接调用,而是用new来调用,形如:

Person p = new Person("LiMing",20);

此时我们就创建了一个Person的对象p,姓名为LiMing,年龄为20,当要使用这个对象进行函数调用和取对象字段值时,形式为:

//对象名.字段名
//对象名.方法名();
Console.WriteLine(p.name);   //输出对象的名称字段值
p.SayHello();                //调用SayHello()方法
  • 方法的重载(overloading)

所谓方法重载,就是相同的函数名,但是返回值类型,形参个数,形参值类型等不完全一样的函数,举一个最简单的例子:

//同一个函数名F(),但不是同一个函数
void F();
void F(int x);
void F(int x,int y);
int F(string s);
int F(int y);

在C#中还有下面这种用法:

public void SayHello() { //签名SayHello();Console.WriteLine("Hello! My name is " + name);
}public void SayHello(Person another) { //签名SayHello(Person)Console.WriteLine("Hello," + another.name + "! My name is " + name);
}

其中,方法的签名由方法名称、参数类型、参数修饰符构成,目前这个用的并不多,所以只见到认识即可。

  • 使用this

这个this指的是当前对象本身,常用于以下情况:

  1. 访问这个对象的字段及方法(vs会智能提示)
  2. 区分字段与局部变量
public Person(int age,string name){this.age = age;this.name = name;
}

3.用于构造方法调用另一个构造方法,注意位置

public Person():this(0,""){//构造方法的其它语句;
}

这里用的最多的就是第二种,我们在构造函数对字段进行初始化的时候可以避免混淆,另外两种并未作过多说明。

  • 属性

注意,这里是C#的特点之一了,属性(property)用于表达事物的状态,前面说字段也是表示事物状态的,怎么回事呢?其实,属性使用另一种方式事物的状态,它可以获取和设置事物的状态,属性的存取方式可以是读,也可以是写,读属性和写属性分别用get和set进行表示。

一般形式及示例:

/*修饰符 类型名 属性名{get{}set{}
}
*/
public string Name{get{return_name;}set{_name = value;}
}
/*在属性的“获取方法”(get方法)中,用return来返回一个事物的属性值
在属性“设置方法”(set方法)中可以使用一个特殊的value变量,该变量包含用户指定的值,通常在set方法中,将用户指定的值记录到一个字段变量中,这里set、get和value被称为上下文关键字
*/

其中在C#3以上版本中可以简写为:

public string Name{set;get;}

注意:按照惯例,属性首字母大写,而字段首字母小写。

访问属性时,实际上是调用相应的set和get方法,使用采用以下形式:

//对象.属性
Person p = new Person();
p.Name = "LiMing";
Console.WriteLine(p.Name);
  • 属性与字段的比较

属性实际上是方法,可以只读或只写(只有get和set),可以进行有效性检查(if...),可以是计算得到的数据,如下:

public string Info{get{return "Name:" + Name + ", Age: " + Age;
}

另外,还可以定义抽象属性。

  • 索引器(Indexer)

索引器也是一种函数式的成员,可以使得对象能用下标来得到一个值。定义索引器为类创建了“虚拟数组”,该类的实例可以使用[](数组访问运算符)进行访问。

形式:

/*修饰符 类型名 this[参数列表]{set{}get{}
}
*/

使用索引的形式:

/*
对象名[参数]
*/

这里给出属性和索引的简单比较:

属性 索引器
通过名称标识 通过参数列表进行标识
通过简单名称来访问 通过[]运算符来访问
可以用static修饰 不能用static修饰
属性get访问器没有参数 索引的get访问器具有与索引相同的参数列表
属性的set访问器包含隐式value参数 除value参数外,索引的set访问器还具有与索引相同的参数列表
  • 继承(inheritance)

这次我们给出简单的继承说明和实例:C#中都是采用单继承,即一个子类只能有一个父类,但是一个父类可以有多个子类,所有的类都是通过直接或间接地继承object(即System.Object)得到的。

先给一个简单的形式:

class SubClass:BaseClass{//...
}

说明:

  • 子类自动的从父亲那里继承所有的字段、方法、属性、索引器等作为自己的成员。
  • 除了继承父类的成员外,子类还可以添加新的成员,隐藏或修改父类的成员。

这里我们着重说一下这个隐藏,其实就是重新定义一个从父类哪里继承来的字段变量完全相同的变量,实际上用得少,但需要注意下:

class A{public int a;
}
class B:A{new public int a;
}
  • 与父类同名的方法

一是定义同名、但是参数列表(签名)与父类不同的方法,这称为对父类方法的重载

二是定义同名且参数列表也与父类相同的方法,这称为新增加一种方法,用new表示(实际较少用)

三是定义同名且参数列表也与父类相同的方法,而且父类的方法用了abstract或virtual进行了修饰,子类的同名方法用了override进行了修饰,这称为虚方法的重写或覆盖(实际使用多)

  • 使用base

使用base访问父类的字段和方法

override void sayHello(){base.sayHello();Console.WriteLine("My school is " + school);
}

使用父类的构造方法:

Student(string name,int age,string school):Person(name,age){this.school = school;...
}

下面在介绍几个C#关于继承的特性:

  • 父类与子类的转换
Personp1 = new Person();
Person p2 = new Student();
Student s1 = new Student();
Student s2 = new Student();
p1 = s1; //可以,因为Person类型的变量可以引用Student对象
s2 = p1; //不行,因为会产生编译错误
s2 = (Student) p1; // 编译时可以通过,运行时则会出现类型不能转换的异常
s2 = (Student) p2; //正确,因为p2引用的正好是Student对象实例
  • as运算符

如果不能转换,则值为null

Student s3 = p1 as Student; //结果s3为null
Student s4 = p2 as Student; //s4被赋值

与强制类型转换的差别

//as只能针对引用型变量
//如果不能转换,as运算不会引起异常,只是值为null
  • is运算符
if(p is Person)
//判断一个对象是不是某个类的实例
  • Typed()运算符

获得其运行时的类型:

Type t = typeof(变量);
Type t = typeof(类名);
  • 属性、索引的继承
/*
属性、索引也是可以继承的
• 子类也可以增加属性和索引器
• 子类还可以定义与父类同名或同参数列表的属性或索引器(通
过new或overide)
*/

行吧,这一节就先写到这吧,学习语言最重要的就是要写要练,一起加油吧!!

C#入门-Person类相关推荐

  1. c#图像处理入门(-bitmap类和图像像素值获取方法)

    c#图像处理入门 -bitmap类和图像像素值获取方法 一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义 ...

  2. JDBC概念快速入门工具类Util的写法

    JDBC概念&快速入门&工具类Util的写法 概念 Java Database Connectivity Java 数据库连接,用Java语言操作数据库 JDBC本质:官方定义的一套操 ...

  3. python入门笔记——类和对象⑤(继承)

    python入门笔记--类和对象⑤(继承) # python中展现面向对象的三大特征:封装.继承.多态 # 封装:把内容封装到某个地方以便后续的使用 # 对封装来说,其实就是使用初始化构造方法将内容封 ...

  4. ExtJS入门之一 类与继承

    在项目中使用ExtJS已经有一段时间了, 对于这个庞大的Script类库有了一定的了解, 在Ext的使用上也有了一定的经验, 现将这些经验做一下总结, 作为一个入门材料给大家分享. 对于Ext库, 不 ...

  5. Kotlin入门(13)类成员的众生相

    上一篇文章介绍了类的简单定义及其构造方式,当时为了方便观察演示结果,在示例代码的构造函数中直接调用toast提示方法,但实际开发是不能这么干的.合理的做法是外部访问类的成员属性或者成员方法,从而获得处 ...

  6. Kotlin入门(12)类的概貌与构造

    上一篇文章提到泛型函数appendString是在类外面定义,这不免使人疑惑,类里面又该怎样定义成员函数呢?为解答这个疑问,接下来的几篇文章将好好描述一下Kotlin如何操作类及其对象,本篇文章先对类 ...

  7. react基础入门,类组件和函数组件,state,props,refs

    React入门 目录 React入门 React入门 Vue跟React的异同点 相同点 不同点 Vue小建议 1. 不需要响应式的数据应该怎么处理? 2. Key 3. 数据结构 React 教程 ...

  8. 学习笔记:C++初阶【C++入门、类和对象、C/C++内存管理、模板初阶、STL简介、string、vector、list、stack、queueu、模板进阶、C++的IO流】

    文章目录 前言 一.C++入门 1. C++关键字 2.命名空间 2.1 C语言缺点之一,没办法很好地解决命名冲突问题 2.2 C++提出了一个新语法--命名空间 2.2.1 命名空间概念 2.2.2 ...

  9. C++入门学习 类与对象

    类与对象 普通大一新生,C++入门.老师上课不讲课只看视频讲解,效率低.临近期末总结巩固已经学习过的内容. 一.构造函数 定义 类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数-> ...

  10. python3 入门 (四) 类与继承

    Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法. 对象可以包含任意数量和类型的数据. p ...

最新文章

  1. python编程语言是什么-Python编程语言的特点是什么?老男孩Python学习
  2. C语言数组作为传入参数
  3. css平台HTDC币,是否应该从最新的设置中应用CSS规则?
  4. no ip domain-lookup 什么意思
  5. Linux下查看文件和文件夹大小的df和du命令(链接)
  6. postman替换快捷键ctrl加什么_电脑截图快捷键ctrl加什么
  7. TreeView控件问题汇总
  8. 【报告分享】2020直播电商分析报告-抖音VS快手.pdf(附下载链接)
  9. (一)Redis初学教程之安装篇
  10. CSV读取大文件报错_csv.Error: field larger than field limit
  11. 人脸对齐实现“平均脸”制作
  12. 如何下载B站视频,解决视频没有声音/音画分离问题(IDM+Potplayer)
  13. 【latex】Latex解决表格过宽问题,自适应调整宽度;自动调整适合的表格大小
  14. 知识图谱-生物信息学-医学顶刊论文(Bioinformatics-2022)-SGCL-DTI:用于DTI预测的监督图协同对比学习
  15. FYD-Focus Your Distribution-关注你的分布:异常检测和定位的从粗到细的非对比性学习-FYD
  16. h5的开源播放器组件
  17. PN结正向压降温度特性的研究
  18. 经典语录 -- 心情down或者hot的时候 来瞅瞅 有新的收获 同时也要留下足迹
  19. 全球与中国高压高温金刚石市场产业运行形势分析及前景趋势预测报告2022-2028年
  20. Kai Ge - 8K壁纸V1.0

热门文章

  1. 用JAVA实现简单的WORD转PDF 亲测有效
  2. 接口测试用例怎么写? 模板示例 2021
  3. 阿里巴巴的矢量图标库
  4. python编程源码
  5. HINSTANCE+hPreInstance
  6. 如何在html中选择wrap,jQuery wrap()方法怎么用?
  7. 2022新版云进销存系统ERP销售库存仓库员工管理系统源码
  8. 记一次bro+pf_ring zc的搭建历程
  9. Matlab矩阵的定义与构建
  10. PostgreSQL函数——数值函数