16.面向对象-继承-继承中的构造函数
16.1 知识点
知识回顾
构造函数的作用
- 实例化对象时调用的函数
- 主要用来初始化成员变量
- 每个类都会有一个默认的无参构造函数
构造函数的语法
访问修饰符 类名()
{
// 构造函数体
}
构造函数的特点
- 不写返回值
- 函数名和类名相同
- 访问修饰符根据需求而定,一般为public
- 构造函数可以重载
- 可以用this语法重用代码
构造函数的注意事项
- 有参构造会顶掉默认的无参构造
- 如果想保留无参构造,需要重载出来
构造函数的实例
class Test
{
public int testI;
public string testStr;
public Test() { }
public Test(int i)
{
this.testI = i;
}
public Test(int i, string str) : this(i)
{
this.testStr = str;
}
}
继承中的构造函数
特点
- 当申明一个子类对象时,先执行父类的构造函数,再执行子类的构造函数
- 注意:
- 父类的无参构造很重要
- 子类可以通过
base
关键字代表父类调用父类构造
继承中构造函数的执行顺序
class语句块外 namespace语句块内
// 父类的父类的构造——>。。。父类构造——>。。。——>子类构造
//游戏对象类
class GameObject
{
public GameObject()
{
Console.WriteLine("GameObject的构造函数");
}
}
//玩家类
class Player : GameObject
{
public Player()
{
Console.WriteLine("Player的构造函数");
}
}
//主玩家类
class MainPlayer : Player
{
public MainPlayer()
{
Console.WriteLine("MainPlayer的构造函数");
}
}
主函数内
MainPlayer mainplayer = new MainPlayer();
//GameObject的构造函数
//Player的构造函数
//MainPlayer的构造函数
父类的无参构造函数的重要性
class语句块外 namespace语句块内
//父类
class Father
{
//当父类无参构造函数被顶掉或者不存在的时候
//子类会报错,因为Son son = new Son(); 会默认调用父类的无参构造函数
//public Father() { }
public Father(int i)
{
Console.WriteLine("Father的一个参数的构造");
}
}
//子类
class Son : Father
{
//子类内
//通过base调用Father的一个参数的构造函数
public Son(int i) : base(i)
{
Console.WriteLine("Son的一个参数的构造");
}
//通过this调用Son的一个参数的构造函数
public Son(int i, string str) : this(i)
{
Console.WriteLine("Son的两个参数的构造");
}
}
主函数内
//Son son = new Son();//报错,父类无参构造函数被顶掉或者不存在
通过base调用指定父类构造
子类内
//子类
class Son : Father
{
//子类内
//通过base调用Father的一个参数的构造函数
public Son(int i) : base(i)
{
Console.WriteLine("Son的一个参数的构造");
}
//通过this调用Son的一个参数的构造函数
public Son(int i, string str) : this(i)
{
Console.WriteLine("Son的两个参数的构造");
}
}
主函数内
Son son = new Son(1, "123");
//Father的一个参数的构造
//Son的一个参数的构造
//Son的两个参数的构造
总结
- 继承中的构造函数的特点:
- 执行顺序是先执行父类的构造函数,再执行子类的,从老祖宗开始,依次一代一代向下执行
- 父类中的无参构造函数很重要,如果被顶掉,子类中就无法默认调用无参构造了
- 子类使用父类构造函数时报错的解决方法:
- 始终保持申明一个无参构造
- 通过
base
关键字调用指定父类的构造
- 注意:区分
this
和base
的区别,base
是调用父类,this
是调用自己
16.2 知识点代码
using System;
namespace Lesson14_继承_继承中的构造函数
{
#region 知识回顾
//构造函数的作用
//实例化对象时调用的函数
//主要用来初始化成员变量
//每个类 都会有一个默认的无参构造函数
//构造函数的语法
// 访问修饰符 类名()
// {
// }
//构造函数的特点
//不写返回值
//函数名和类名相同
//访问修饰符根据需求而定,一般为public
//构造函数可以重载
//可以用this语法重用代码
//注意
//有参构造会顶掉默认的无参构造
//如想保留无参构造需重载出来
//实例
class Test
{
public int testI;
public string testStr;
public Test()
{
}
public Test(int i)
{
this.testI = i;
}
public Test(int i, string str) : this(i)
{
this.testStr = str;
}
}
#endregion
//class语句块外 namespace语句块内
#region 知识点一 继承中的构造函数 基本概念
//特点
//当申明一个子类对象时
//先执行父类的构造函数
//再执行子类的构造函数
//注意:
//1.父类的无参构造 很重要
//2.子类可以通过base关键字 代表父类 调用父类构造
#endregion
#region 知识点二 继承中构造函数的执行顺序
// 父类的父类的构造——>。。。父类构造——>。。。——>子类构造
//游戏对象类
class GameObject
{
public GameObject()
{
Console.WriteLine("GameObject的构造函数");
}
}
//玩家类
class Player:GameObject
{
public Player()
{
Console.WriteLine("Player的构造函数");
}
}
//主玩家类
class MainPlayer : Player
{
public MainPlayer()
{
Console.WriteLine("MainPlayer的构造函数");
}
}
#endregion
#region 知识点三 父类的无参构造函重要
//子类实例化时 默认自动调用的 是父类的无参构造 所以如果父类无参构造被顶掉 会报错
//父类
class Father
{
//当父类无参构造函数被顶掉或者不存在的时候
//子类会会报错 因为Son son = new Son(); 会默认调用父类的无参构造函数
//public Father()
//{
//}
public Father(int i)
{
Console.WriteLine("Father的一个参数的构造");
}
}
//子类
class Son :Father
{
#region 知识点四 通过base调用指定父类构造
//子类内
//通过base调用Father的一个参数的构造函数
public Son(int i) : base(i)
{
Console.WriteLine("Son的一个参数的构造");
}
//通过this调用Son的一个参数的构造函数
public Son(int i, string str) : this(i)
{
Console.WriteLine("Son的两个参数的构造");
}
#endregion
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("继承中的构造函数");
//主函数内
#region 知识点二 继承中构造函数的执行顺序
MainPlayer mainplayer = new MainPlayer();
//GameObject的构造函数
//Player的构造函数
//MainPlayer的构造函数
#endregion
#region 知识点三 父类的无参构造函重要
//Son son = new Son();//报错 父类无参构造函数被顶掉或者不存在
#endregion
#region 知识点四 通过base调用指定父类构造
Son son = new Son(1, "123");
//Father的一个参数的构造
//Son的一个参数的构造
//Son的两个参数的构造
#endregion
}
}
//总结
//继承中的构造函数的特点:
//执行顺序 是先执行父类的构造函数 再执行子类的 从老祖宗开始 依次一代一代向下执行
//父类中的无参构造函数 很重要 如果被顶掉 子类中就无法默认调用无参构造了
//子类使用父类构造函数时报错的解决方法:
//1.始终保持申明一个无参构造
//2.通过base关键字 调用指定父类的构造
//注意:区分this和base的区别 base是调用父类 this是调用自己
}
16.3 练习题
打工人基类及其派生类
程序员、策划、美术分别继承打工人
请用继承中的构造函数这个知识点
实例化3个对象,分别是程序员、策划、美术
class语句块外 namespace语句块内
//打工人类
class Worker
{
public string type;
public string content;
public Worker(string type, string content)
{
this.type = type;
this.content = content;
}
public void Work()
{
Console.WriteLine("{0}{1}", type, content);
}
}
//程序员类
class Programmer : Worker
{
public Programmer() : base("程序员", "编程")
{
}
}
//策划类
class Plan : Worker
{
public Plan() : base("策划", "设计游戏")
{
}
}
//美术类
class Art : Worker
{
public Art() : base("美术", "画画")
{
}
}
主函数内
// 主函数内
Programmer p = new Programmer();
p.Work();
//程序员编程
Plan p2 = new Plan();
p2.Work();
//策划设计游戏
Art p3 = new Art();
p3.Work();
//美术画画
在这里,通过构造函数的继承,每个派生类在实例化时就会调用基类的构造函数,从而初始化特征属性。这样,通过继承和构造函数的组合,可以更方便地创建具有相似特征和行为的类。
16.4 练习题代码
using System;
namespace Lesson14_练习题
{
#region 练习题一
//有一个打工人基类,有工种,工作内容两个特征,一个工作方法
//程序员、策划、美术分别继承打工人
//请用继承中的构造函数这个知识点
//实例化3个对象,分别是程序员、策划、美术
//class语句块外 namespace语句块内
//打工人类
class Worker
{
public string type;
public string content;
public Worker(string type, string content)
{
this.type = type;
this.content = content;
}
public void Work()
{
Console.WriteLine("{0}{1}", type, content);
}
}
//程序员类
class Programmer:Worker
{
public Programmer():base("程序员", "编程")
{
}
}
//策划类
class Plan:Worker
{
public Plan():base("策划", "设计游戏")
{
}
}
//美术类
class Art:Worker
{
public Art():base("美术", "画画")
{
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("继承中的构造练习题");
#region 练习题一
Programmer p = new Programmer();
p.Work();
//程序员编程
Plan p2 = new Plan();
p2.Work();
//策划设计游戏
Art p3 = new Art();
p3.Work();
//美术画画
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com