【C#学习记录】四、面向对象基础概念(2)
继承
基本概念
我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类
子类 派生类
父类 基类
子类继承了父类,那么子类从父类那里继承过来了什么?
首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。
问题:子类有没有继承父类的构造函数?
答:子类没有继承父类的构造函数,但是,子类会默认的调用父类无参数的构造函数,创建父类对象,让子类可以使用父类中的成员。
所以,如果在父类中重新写了一个有参数的构造函数之后,那个无参数的构造函数就被干掉了,子类就调用不到了,所以子类会报错,
解决办法:
- 在父类中重新写一个无参数的构造函数。
- 在子类显示的调用父类的构造函数,使用关键字:base()
继承的特性
- 继承的单根性:一个子类只能有一个父类。
- 继承的传递性
- 所有类都继承于object类
- 子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。
查看类图
visual studio2022看不了类设计器
关键字new
1. 创建对象
2. 隐藏从父类继承过来的同名成员
里氏转换
基本概念
-
子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替
Student s = new Student(); Person p = s; //Person p = new Student();
-
如果父类中装的是子类对象,那么可以将这个父类强转为子类对象。
Student ss = (Student)p;
-
is 和as
-
is 表示类型转化,如果能够转换成功,则返回一个true,否则返回一个false
if(p is Student) { Student ss = (Student)p; } else { Console.WriteLine("转换失败"); }
-
as 表示类型转换,如果能够转换则返回对应的对象,否则返回null
Student t = p as Student;//将p转换成Student类
-
protected关键词
受保护的,可以在当前类的内部以及该类的子类中进行引用。
装箱与拆箱
装箱:就是将值类型转换为引用类型。
拆箱:就是将引用类型转换为值类型。
int n = 10;
object o = n;//装箱
int nn = (int)o;//拆箱
装箱操作耗费系统时间。
using System.Collections;
using System.Diagnostics;
Stopwatch sw = new Stopwatch();
ArrayList al = new ArrayList();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
al.Add(i);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
List<int> ls = new List<int>();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
ls.Add(i);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
执行结果
但是从执行结果看,使用泛型list时间非常长,不知道为什么
Answer:因为Stopwatch在Stop后,是暂停。如果要执行下一次任务,需要Reset()重置一下才行。
using System.Collections;
using System.Diagnostics;
Stopwatch sw = new Stopwatch();
ArrayList al = new ArrayList();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
al.Add(i);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
List<int> ls = new List<int>();
sw.Reset();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
ls.Add(i);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
执行结果:
看两种类型是否有可能发生装箱和拆箱,要看,这两种类型是否存在继承关系。例如下面的代码,是没有发生装箱或拆箱的。
string str = "123";
int n = Convert.ToInt32(str);
本文来自博客园,作者:翻兽,转载请注明原文链接:https://www.cnblogs.com/xuzhq/p/15933894.html