继承
1.命名空间
在我看来,命名空间类似于C中的源文件,命名空间有很多的类,当我们使用某个类的时候,如果此项目中没有此声明,需要我们手动输入此文件。
例如:
using System;
using System.Data;
using System.IO;
- 当我们突然需要某命名空间时,我们可以手动输入或者使用快捷键进行。
- 将光标放到你使用的某个类
- 快捷键:ALT+SHIFT+F10
- 当我们想在一个项目中使用另一个项目中的类的时候:
- 在本项目的控制台那边右键点击,然后点击添加引用,添加你所需要的项目;
- 添加完成后,需要在此项目中手动输入命名空间:using 项目名字
2.值类型和引用类型简介
区别:
- 值类型和引用类型存储的位置不一样。
- 在传递值类型和引用类型的时候,传递的方式不一样。
值类型:int,double,bool,char,decimal,struct,enum。
引用类型:string,数组,自定义类。
存储:
- 值类型的值是存储在内存的栈当中。
- 引用类型的值是存储在内存的堆当中。
3.继承
- 什么是继承:
我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类。
父类——子类
- 语法:
[public] class 子类类名:父类类名
注意:子类可以赋值给父类。
- 子类会从父类继承什么?
子类继承了父类的属性和方法,但是,父类的私有字段并没有被继承。
- 子类能否继承父类的构造函数?
1.子类并没有继承父类的构造函数,但是子类会默认调用父类无参数的构造函数,相当于创建了一个父类对象,让子类可以使用父类中的成员。而且子类执行完父类的无参构造函数之后再执行了自己的无参构造函数
2.如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,子类就调用不到了,此时就会报错。
解决办法:
1.在父类中重新写一个无参数的构造函数
2.在子类中显示的调用父类的构造函数,使用关键字:base()
//随便举个例子,了解下base()的用法
public class Person
{
private string _name;
private int _age;
private char _gender;
public Person(string name,int age,char gender)
{
this._name = name;
this._age = age;
this._gender = gender;
}
}
public class Student:Person
{
private int _id;
public Student(string name,int age,char gender,int id)
:base(name,age,gender)
{
this._id = id;
}
}
- 继承的特点:
1.继承的单根性:一个子类只能拥有一个父类
2.继承的传递性:一个继承父类的子类也是另一个子类的父类,依次可继续套娃。
- new关键字:
1.可以用new关键字来创建对象。
2.当我们在父类和子类中使用了同样的名称命名一个方法时,发现子类对象只能调用到自己的方法,父类的无法调用。new关键字还可以隐藏从父类那里继承的同名成员,隐藏的后果就是子类调用不到父类的成员。
4.里氏转换
- 子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替,但是子类对象可以调用父类中的成员,父类对象永远都只能调用自己的成员。
语法:
父类 类名 = new 子类()
- 如果父类中装的是子类对象,那么可以将父类强转成子类对象
语法:
(子类名) 父类对象名字
前提:父类里面所装的是指定子类对象
例如:
Person p = new Student();//前提
student ss = (student)p;
//如果所转的子类与父类所装的子类对象不一样,则会抛异常
注意:
判断是否强转成功:
is:如果转换成功,会返回一个true,失败,则返回false
as: 转换失败会返回一个null
//is的用法
Person p = new Student();
student ss = (student)p;
if( p is Student)
{
student ss = (student)p;
}
else
{
Console.WriteLine("转换失败");
}
//as的用法
Student ss = p as Student
t.studentSayHell0();//转换成功,则输出子类的方法。
5.protected访问修饰符
访问修饰符:protected、public、private
访问权限:只有子类或者在父类里面才能访问其父类,非子类不能访问父类。