数往知来C#面向对象〈三〉
C# 基础方法篇
一、复习
1)方法的重载
方法的重载并不是一个方法,实际上方法的重载就是一些不同的 方法,目的是为了方便程序员编码,所以将功能相近的方法命名相同
根据参数,编译器自动的去匹配方法体,而不需要程序员记住 的方法
--》如何判断重载写的对不对
将方法的定义拿出来,去掉修饰符,去掉方法体,去掉返回类型
int InputNum()
int InputNum(int max)
int InputNum(int min,int max)
-->将参数列表中的局部变量名去掉,只留参数类型
int InputNum()
int InputNum(int )
int InputNum(int ,int )
二、封装
-》属性是对字段的封装
-》 方法是对过程的封装
-》类是对对象的封装(特性和功能)
-》程序集是对类库的封装
C# 基础继承篇
为什么使用继承?
-》代码的重用
-》实现多态(里氏转换)
继承中类分为父类(基类)与子类(派生类)
基类
将具有共同特征的这个类,单独写出来,称为父类(基类)
子类
继承父类所有的特征,也可以有属于自己不同的特征。
父类(基类):把这个类的对象都具有的一些特征和行为等都封装到这个类里面。
然后由这个父类派生出子类(派生类),这些子类会把父类里的特征(属性)行为(方法)等继承下来。从而实现代码的重用
例如:
class Person
{
string _name;
int _age;
char _sex; public string Name
{
get { return _name; }
}
public int Age
{
get { return _age; }
}
public char Sex
{
get { return _sex; }
}
public Person(string name,int age,char sex)
{
_sex = sex;
_name = name;
_age = age;
}
public void SayHello()
{
Console.WriteLine("大家好,我叫{0},今年{1}岁了,我是{2}生",_name ,_age ,_sex );
}
}
class student : Person
{
public student(string name,int age,char sex):base(name,age,sex)
{
//方法体
}
public void SayHello()
{
Console.WriteLine("大家好,我叫{0},今年{1}岁了,我是{2}生",Name ,Age ,Sex );
}
}
这里student类是person的派生类,它继承了person类的所有成员包括SayHello方法,这里Student的sayhello方法把父类的sayhello方法给隐藏了
继承的特征
-》单根性(只能继承一个基类)
-》传递性(子类可以继承基类的成员。字段、属性、方法等)
-》 派生于object根类(基于C#)(为什么要有根类?还是为了实现多态)
注意问题
-》构造方法的问题
创建对象的时候,好像是先调用子类构造方法,然后由子类再调用父类构造方法,
再调用构造方法的时候,其实默认有一个base(),调用了父类的无参构造方法
语法:
class 基类
{
//基类成员
}
class 子类:基类
{
//子类可以有自己的成员
//基类的成员也会被继承下来
}
子类于父类构造方法的执行顺序
Student student = new Student();
这里New子类对象时会先走到子类的构造方法,这里系统会默认提供一个base()无参的构造方法。如果父类中有了有参的构造方法,系统就不会再分配无参的构造方法,
此时如果子类调用父类的构造方法就会报错,因为父类的无参构造方法已经没有了。解决办法由两个
1)再手动在父类中添加一个无参的构造方法。
2)base(参数列表)传参数上去。
public student(string name,int age,char sex):base(name,age,sex) 这里不执行下面的大括号,然后base调用父类的构造方法,如果父类上面还有父类会依次往上调,
直到调到最上面的父类执行完最上面的父类构造方法然后再依次的往下执行回到这个子类,执行剩下的方法体
{
//方法体
}
this和base关键字:
this表示当前类 当前构造方法
base表示父类 父类构造方法
经典例子:
class MyClass
{
public MyClass():this()
{
Console.WriteLine();
}
public MyClass(int i):this(,)
{
Console.WriteLine(i);
}
public MyClass(int i, int j)
{
Console.WriteLine("{0}{1}",i,j);
}
}
class Program
{
static void Main(string[] args)
{
MyClass myclass = new MyClass();
}
}
在new对象时首先会跳到无参的构造方法,此时看到有一个this(3),不执行方法体,在本类中寻找匹配带一个参数的构造函数,然后调用,
此时又看到一个this(2,3),又在本类中寻找匹配带两个参数的构造函数,最后调用带两个参数的构造函数,执行带两个参数的方法体,
完毕之后又回到带一个参数的构造函数中执行方法体,最后再跳会无参的构造函数中执行无参的构造函数的方法体。
C# 基础多态篇
四、访问修饰符
privete 只有在本类中访问
public 任何地方都可以访问
protected 只能在当前类和子类中访问
internal 只允许在当前类中访问
protectecd internal
里氏转换
1)子类可以直接赋值给父类(子类对象可以直接转换为父类对象)隐式转换
2)如果满足第一个条件的父类对象,可以强制转换为原来的子类对象。 强制转换
强制转换可以通过 is 和 as 来判断
is:
语法 bool b=要转换的对象 is 要转换的类型
如果可以转换就会返回一个true,如果转换不合法就会返回一个false.
IS操作符很清晰,但是操作效率不高,另种方式是AS
as:
语法 要转换的类型 对象=要转换的对象 as 要转换的类型
as操作首先测试是否合法,如果合法就转换,如果不合法就返回null,null表示空引用
五、new和override
new隐藏基类方法: 前提是子类和父类的方法名参数返回值都一样,这时候写new和不写new没上面区别。
class MyBase
{
public void Func()
{
Console.WriteLine("我是父类");
}
}
class MySub : MyBase
{
public void Func()
{
Console.WriteLine("我是子类");
}
}
这时候子类的方法会把父类的方法隐藏掉,这时候对象是什么类型就调用什么类型的方法。
override重写基类方法:子类要重写基类的方法,父类的方法必须要有virtual 表明是虚方法,可以被子类重写。
一旦父类的方法被重写,父类的方法将不复存在,调用的时候会调用重写之后的新的方法。
C# 基础关于构造方法的调用
class Person //基类人类
{
//如何在子类中访问父类的字段
//分别定义三个字段 属性
//字段的访问修饰符设定为 protected 这样在子类中便可以访问这个字段
//protected表示当前类和子类可以访问
protected string _name; public string Name
{
get { return _name; }
}
protected int _age; public int Age
{
get { return _age; } } protected char _gender; public char Gender
{
get { return _gender; }
}
//写一个构造方法 将字段初始化赋值
public Person(string name, int age, char gender)
{
this._name = name;
this._age = age;
this._gender = gender;
}
//定义一个无参的构造方法,这样的话子类才能调用父类的构造函数,避免子类要调用无参的构造方法时出错。
public Person()
{
} }
//定义一个supperman子类 继承自 person
class SupperMan : Person
{ //子类独有字段 特征
private string _state; public string State
{
get { return _state; }
}
public SupperMan(string name, int age, char gender, string state) //这里不写base()默认调用父类无参的构造方法,写与不写都一样
{
base._name = name;
base._age = age;
base._gender = gender;
base._state = state; //*this 是表示这是该类中的一个字段 //*base则表示这是一个从父类中继承过来的字段 //*在这里 this 与base可以不写 是写给程序员看的
}
public void Hello()
{
Console.WriteLine("大家好,我叫{0},我的年龄是{1},我是{2}人,我的特征是{3}",Name,Age,Gender,State);
}
} class Program
{
static void Main(string[] args)
{
SupperMan supperMan = new SupperMan("超人", , '男', "内裤外穿");
supperMan.Hello();
Console.ReadKey();
}
}
C# 基础构造方法篇
2)构造方法
--》没有继承关系
-》默认构造方法(无参的构造方法)
没有提供构造方法的时候, 系统自动的添加一个无参的构造方法
如果已经写了构造方法,那么系统就不会自动的添加默认的构造方法(手动添加)
-》构造方法也有重载
调用
this(当调用制定构造方法后有this的时候,会先调用this表示的重载,再调用自己的构造方法)
--》有继承关系
-》默认调用父类的构造方法
-》使用base可以指定调用父类构造方法
静态构造方法
静态构造方法从程序的开始到结束只会被调用执行一次,当new对象或者访问这个类的字段或属性等时就会调用执行,
C# 基础多态加强篇
多态实现的前提:
-》继承
-》子类父类方法名必须相同
里氏转换原则(只是实现多态的一个条件不是前提)
-》父类 父类对象=new 子类();
。。。
子类 子类对象=(子类)父类对象 必须满足上面的条件这里才能转换成功
隐藏基类的方式
只需要在子类的方法前写上new关键字即可(不写也可以,系统会自动添加)
隐藏看类型
class Person
{
public void SayHello()
{
Console.WriteLine("依依呀呀");
}
}
class American : Person
{
public new void SayHello()
{
Console.WriteLine("Hello");
}
}
class Korean : Person
{
public new void SayHello()
{
Console.WriteLine("啊你哟哈撒哟");
}
}
重写基类方法
-》在父类方法前加上virtual
-》在子类方法前加上override
重写只管新
class Person
{
public virtual void SayHello()
{
Console.WriteLine("依依呀呀");
}
}
class American : Person
{
public override void SayHello()
{
Console.WriteLine("Hello");
}
}
class Korean : Person
{
public override void SayHello()
{
Console.WriteLine("啊你哟哈撒哟");
}
}
二、产生随机数
Random:专门处理随机数的类。(伪随机数,其运行原理是:先得到系统的当前时间(精确到毫秒),然后根据系统的当前时间计算出一个数(就是所谓的伪随机数))
--》创建随机对象
Random r=nrw Radom();
注意: 随机数的对象不要创建在循环里 不然会得到一些重复一样的数字
-->调用Next方法的得到随机数
-》next方法有三个重载
int res=r.netx(); 产生一个非负数的随机数
int res=r.next(100); 产生一个0到99的随机数,两端可以取到
int res=r.next(2,30);产生一个2到29的随机数,两端可以取到
记录时间的类
Stopwath:
Stopwath stop=new Stopwath();
stop.start(); 开始计算
.....
stop.Stop(); 停止计算
console.writeLine(stop.Elapsed); 得到计算结果
多态:为了程序的可扩展性
-》开放封闭的原则(对扩展开放,对修改封闭)
多态的使用:
将不同的对象都当做父类来看,屏蔽掉各个对象间的不同,写出通用代码,做出通用编程,
三、抽象类
什么是抽象方法
有些时候父类的方法不需要实现
有些时候不知道怎么实现
没有方法体的方法叫做抽象方法,使用abstact修饰,
包含抽象方法的类,也必须是一个抽象类。
抽象类中可以包含非抽象成员
抽象方法的用法和虚方法的用法完全一样
不同的是他们的定义不一样,抽象类不可以实例化
抽象类存在就是为了被继承的,因此不允许定义为private.
抽象类不能实例化,比一般类多一抽象成员
抽象类与一般类有两个最大的区别
--》不能实例化
--》 具有抽象成员 ( 凡是跟方法有关的都可以抽象)
-》方法
-》属性
-》索引器(带参数的属性)
-》事件的声明(可以看做“属性”,属性石一个get set方法,事件是add remove方法)
使用抽象属性的时候,一般是抽象类提供属性以及可访问性
子类提供字段与属性的实现
public abstract string s
{
get; //这里的属性和自动属性长得很像,但是要注意他们的含义不一样,这里由abstract修饰就是告诉系统,这里是抽象方法没有方法体,所以这里不用写{}
set; //抽象属性可以只有get或set,因为他可以由构造方法给字段赋值,而自动属性是后台自动生成字段,所以自动属性的get set要成对出现
}
C# 基础重写ToString方法
四、重写ToString方法
string[] str = { "", "", "", "" }; MyClass myClass = new MyClass();
myClass.Name1 = "我是MyClass";
myClass.Name2 = "";
myClass.Name3 = "";
myClass.Name4 = "";
myClass.Name5 = ""; MyStruct myStruct;
myStruct.Name = "我是MyStruct"; Console.WriteLine(str);
Console.WriteLine(myClass);
Console.WriteLine(myStruct);
这里打印数组和类系统会默认调用ToString()方法 任何类型都有一个ToString()方法,因为这个方法是object根类提供的,C#里所有的类都继承自object类,所以object的ToString()会被继承下来。
Reflector可以看到object的ToString()方法是个虚方法,如果子类没有重写,那么系统都会默认调用这个方法,
可以看到这个方法调用 this.GetType()方法 (获得当前实力的命名空间),然后返回
所以上面打印出来的是这个实例所在的命名空间名和实例名。
public virtual string ToString()
{
return this.GetType().ToString();
}
既然父类提供的是虚方法那子类就可以重写,我们可以通过子类重写ToString()方法来实现我们想要显示的内容
class MyClass
{
public string name1;
public override string ToString()
{
return name1;
}
}
class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.name1 = "张三";
Console.WriteLine(myClass);//这里会显示 张三
Console.ReadKey();
}
}
//本系列会持续更新。晚安!
数往知来C#面向对象〈三〉的更多相关文章
- 〈三〉ElasticSearch的认识:搜索、过滤、排序
目录 上节回顾 本节前言 文档的搜索 URL参数条件搜索 请求体条件搜索 语法与示例: 补充: 小节总结: 文档的过滤filter 语法与举例: filter与bool constant_score ...
- 荒芜的周六-PHP之面向对象(三)
hi 又是开森的周六了.积攒的两周的衣服,终于是差不多洗完了.大下午的才来学点东西~~ 1.PHP面向对象(三) 四.OOP的高级实践 4.3 Static-静态成员 <?phpdate_def ...
- C++编程之面向对象的三个基本特征
面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...
- OO面向对象第三次作业总结
面向对象第三次作业总结 一.JML基础梳理及工具链 注释结构 行注释://@annotation 块注释:/*@ annotation @*/ 两种注释都是放在被注释部分上面. 常见表达式 原子表达式 ...
- java面向对象(三)
java面向对象(三) 1.四种权限修饰符 public > protected > (default) > private 注意:(default)并不是关键字default,而是 ...
- 数往知来C#面向对象准备〈二〉
面向对象(OOP→Object-Oriented Programming) 1.什么是面向对象? 一种分析问题的方式. 2.面向对象三大特征: 封装(隐蔽代码实现/复用/修改方便).继承.多态. 3. ...
- 数往知来C#之面向对象准备〈一〉
1.CLR加载编译源文件 注1.:当你点击调试或者生成解决方案的时候这就是一个编译过程首先CLR加载源文件也就是你写的代码(此代码在文件中是字符串)然后将项目中的嗲吗编译成IL代码进而生成程序集 证明 ...
- C++ 面向对象的三个特点--继承与封装(一)
面试的时候经常会有很多概念性的东西,许久不用都会很生疏,特意整理一下方便自己以后不记得了可以查看一下,也顺便帮助自己复习一下. 概念 继承是面向对象程序设计的一个重要特性,它允许在既有类的基础上创建新 ...
- 前端笔记之JavaScript面向对象(三)初识ES6&underscore.js&EChart.js&设计模式&贪吃蛇开发
一.ES6语法 ES6中对数组新增了几个函数:map().filter().reduce() ES5新增的forEach(). 都是一些语法糖. 1.1 forEach()遍历数组 forEach() ...
随机推荐
- Android Touch(3)View的touchDelegate
作用: 基类View有个函数 public void setTouchDelegate(TouchDelegate delegate),给view内部的另一个view设置一个touch代理. 图中vi ...
- Mac 切换Windows 使用虚拟机, 不推荐双系统
为什么使用虚拟机而不是双系统? 1.虚拟机可以随时在两个系统之间进行切换,便于在工作时使用而不影响效率.如果是双系统,在切换到另一个系统时需要关机重启,太过麻烦. 2.虚拟机除了运行Windows之 ...
- WebView中Js与Android本地函数的相互调用
介绍 随着Html5的普及,html在表现力上不一定比原生应用差,并且有很强的扩展兼容性,所以越来越多的应用是采用Html与Android原生混合开发模式实现. 既然要实现混合开发,那么Js与Andr ...
- 如何直接在github网站上更新你fork的repo?
玩过github的人一定会在你自己的账号上fork了一些github开源项目.这些开源项目往往更新比较活跃,你今天fork用到你自己的项目中去了,过几个星期这个fork的origin可能有一些bugf ...
- 【笨嘴拙舌WINDOWS】BMP图片浏览器
要将文件显示成图片这其中需要经过 1.将磁盘文件内容读取到内存: 2.将文件对应内存里包含的像素为以及像素信息转化为显示驱动器能理解的格式: 3.将转化过后的内存送到显卡的缓存区 4.显示器读取缓存现 ...
- jsp之EL表达式
1.null值 null值会用""进行显示 2.隐式对象 1).pageScope.requestScope(相当于request).sessionScope(相当于session ...
- Android Studio 配置使用百度api (附带简单样例)
还是和同学开发的那个课程作业项目的app, 要使用到百度地图的api 但是,官方文档貌似只有Eclipse的例子,对Android Studio似乎没有说明. 难道,是因为后者是 "Doo ...
- 基于EasyUi的快速开发框架
先看图,下边这个简单的增.删.改.查,如果自己写代码实现,这两个页需要多少行代码? 如果再有类似的增.删.改.查,又需要多少行代码? 我最近搞的这个快速开发框架中,代码行数不超过100. 两页的代码如 ...
- POJ 2369 Permutations
傻逼图论. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm& ...
- php设计模式之观察者模式
观察者模式:能够更便利地创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定功能性. 利用这种模式可以方便地创建一个对象(观察者),其可以用来“监视”另一个对象(被观察者)的状态.这样,就可以在 ...