首先,构造器是类中进行说明的特殊的成员方法,构造器的作用是在创建对象时,系统自动调用它来给所创建的对象初始化。此时问题又出来了,为什么不直接初始化对象就好,还要使用一个构造器呢,这不是很多余,其实不然。
当没有定义构造器时每个类里都有一个默认的无参的构造方法,此时该类就只有一个构造器;而当你显示定义类的构造器时,那就没有那个默认的构造方法了,该类所有的构造器就是你已经定义了的那些构造器;
例如:定义一个Student类:
class Student1{
//不定义构造器,此时默认的构造器是new Student1();
//一个对象时只能这样构造,Student1 s=new Studnet1();
}
另外再写一个有定义构造器的类:
class Student2{
Student2(String name){
}
Student2(String name,int age){
}
}
Student2有两个构造器,默认的构造器就没有了
创建Student2对象时只能用两个构造器
Student2 s2=new Student2("xiaoming");
Student2 s3=new Student2("xiaoqiang",12);
这个时候就不能写
Student2 s4=new Student2();
编程中可以提供多个构造器,参数也没有具体限制,这样便打破了默认构造器的编程局限,为大家编程带来了方便。
下面贴出来自己的一个简单的小例子大家可以试着运行体会构造器的使用,
class example{
int mYea;
int mMonth;
int mDay;
example(){
mYear=1986;
mMonth=10;
mDay=17;}
example(int pYear,int pMonth,int pDay){
mYear=pYear;
mMonth=pMonth;
mDay=pDay;}
private void print(){
System.out.println(mYear+"年"+mMonth+"月"+mDay+"日");}
public static void main(String[] arg){
example e1=new example();
example e2=new example(2011,11,12);
System.out.println("------无参构造器-----");
e1.print();
System.out.println("------有参构造器-----"");
e2.print();
}
}
此时对构造器应该有个大体的了解了,那么现在说下构造器的几个特点:
1,构造器是个特殊的方法,他的名字和类名相同。定义和说明构造器时不需要指明返回类型。
2,构造器可以有一个或多个参数,也可以没有。
3,构造器可以被重载。
4,如果类中没有声明构造器,系统会自动添加一个没有参数的默认构造器。
5构造器是类创建时候系统调用的,因此多用于类的初始化。
最后说下一些在使用构造器中的注意事项。
1,构造器中一定不要创建自身的实例,否则会造成调用栈溢出错误。这个规则也适用于对象的实例变量,如果对象中有自身的引用,这个引用一定不能在定义中或者构造器中初始化。 class a { a _a = new a(); public a() { _a = new a(); a _b = new a(); } } 以上三种情况都会造成栈溢出,这样会造成一个无穷递归的调用栈。
2,如果父类是一个抽象类,那通过调用父类的构造器,也可以将它初始化,并且初始化其中的数据。
3,如果要在构造器中调用一个方法时,将该方法声明为private。 对于这个规则是需要一些说明的,假使你的父类构造器中要调用一个非静态方法,而这个方法不是private的又被子类所重载,这样在实际创建子类的过程中递归调用到了父类的构造器时,父类构造器对这个方法的调用就会由于多态而实际上调用了子类的方法,当这个子类方法需要用到子类中实例变量的时候,就会由于变量没有初始化而出现异常(至于为什么子类中的实例变量没有初始化可以参考上边的实例初始化过程),这是Java不想看到的情况。而当父类构造器中调用的方法是一个private方法时,多态就不会出现,也就不会出现父类构造器调用子类方法的情况,这样可以保证父类始终调用自己的方法,即使这个方法中调用了父类中的实例变量也不会出现变量未初始化的情况(变量初始化总是在当前类构造器主体执行之前进行)
练习:奥特曼打小怪兽和Boss
代码:/*********************OutMan***********************/
package cn.trainingcamp;
public class OutMan {
//定义名字和战斗力
private String name;
private int energy;
//设置属性:名字和战斗力
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setEnergy(int energy){
this.energy = energy;
}
public int getEnergy(){
return energy;
}
//设置行为:打boss
public void fight(Boss boss){
boss.setEnergy(boss.getEnergy()-1);
System.out.println(boss.getName()+"被"+name+"攻击了!\n"+boss.getName()+"剩余血量为"+boss.getEnergy());
}
//设置行为:打小怪兽
public void fight(Monster monster){
monster.setEnergy(monster.getEnergy()-2);
System.out.println(monster.getName()+"被"+name+"攻击了!\n"+monster.getName()+"剩余血量为"+monster.getEnergy());
}
}
/*********************Monster***************************/
package cn.trainingcamp;
public class Monster {
//定义名字和战斗力
private String name;
private int energy;
//设置属性:名字和战斗力
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setEnergy(int energy){
this.energy = energy;
}
public int getEnergy(){
return energy;
}
//设置行为:打OutMan
public void fight(OutMan outman){
outman.setEnergy(outman.getEnergy()-1);
System.out.println(outman.getName()+"被"+name+"攻击了!\n"+outman.getName()+"剩余血量为"+outman.getEnergy());
}
}
/***********************Boss*****************************/
package cn.trainingcamp;
public class Boss {
//定义名字和战斗力
private String name;
private int energy;
//设置属性:名字和战斗力
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setEnergy(int energy){
this.energy = energy;
}
public int getEnergy(){
return energy;
}
//设置行为:打OutMan
public void fight(OutMan outman){
outman.setEnergy(outman.getEnergy()-1);
System.out.println(outman.getName()+"被"+name+"攻击了!\n"+outman.getName()+"剩余血量为"+outman.getEnergy());
}
}
/**************************入口主函数*********************************/
package cn.trainingcamp;
public class SmallGame {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//实例化一个OutMan对象
OutMan outman = new OutMan();
outman.setName("奥特曼");
outman.setEnergy(100);
//实例化一个Boss对象
Boss boss = new Boss();
boss.setName("兽神");
boss.setEnergy(50);
//实例化一个Monster对象
Monster monster = new Monster();
monster.setName("小怪兽");
monster.setEnergy(40);
//战斗开始
System.out.println("====================战斗开始!=================\n");
while(outman.getEnergy() > 0 && monster.getEnergy()>0){
outman.fight(monster);
monster.fight(outman);
}
if(monster.getEnergy()<0 ){
System.out.println("战斗结束!\n"+outman.getName()+"胜利!");
}
if(outman.getEnergy()<0 ){
System.out.println("战斗结束!\n"+monster.getName()+"胜利!");
}
while(outman.getEnergy() > 0 && boss.getEnergy()>0){
outman.fight(boss);
monster.fight(outman);
}
if(boss.getEnergy()<0 ){
System.out.println("战斗结束!\n"+outman.getName()+"胜利!");
}
if(outman.getEnergy()<0 ){
System.out.println("战斗结束!\n"+boss.getName()+"胜利!");
}
}
}
当没有定义构造器时每个类里都有一个默认的无参的构造方法,此时该类就只有一个构造器;而当你显示定义类的构造器时,那就没有那个默认的构造方法了,该类所有的构造器就是你已经定义了的那些构造器;
例如:定义一个Student类:
class Student1{
//不定义构造器,此时默认的构造器是new Student1();
//一个对象时只能这样构造,Student1 s=new Studnet1();
}
另外再写一个有定义构造器的类:
class Student2{
Student2(String name){
}
Student2(String name,int age){
}
}
Student2有两个构造器,默认的构造器就没有了
创建Student2对象时只能用两个构造器
Student2 s2=new Student2("xiaoming");
Student2 s3=new Student2("xiaoqiang",12);
这个时候就不能写
Student2 s4=new Student2();
编程中可以提供多个构造器,参数也没有具体限制,这样便打破了默认构造器的编程局限,为大家编程带来了方便。
下面贴出来自己的一个简单的小例子大家可以试着运行体会构造器的使用,
class example{
int mYea;
int mMonth;
int mDay;
example(){
mYear=1986;
mMonth=10;
mDay=17;}
example(int pYear,int pMonth,int pDay){
mYear=pYear;
mMonth=pMonth;
mDay=pDay;}
private void print(){
System.out.println(mYear+"年"+mMonth+"月"+mDay+"日");}
public static void main(String[] arg){
example e1=new example();
example e2=new example(2011,11,12);
System.out.println("------无参构造器-----");
e1.print();
System.out.println("------有参构造器-----"");
e2.print();
}
}
此时对构造器应该有个大体的了解了,那么现在说下构造器的几个特点:
1,构造器是个特殊的方法,他的名字和类名相同。定义和说明构造器时不需要指明返回类型。
2,构造器可以有一个或多个参数,也可以没有。
3,构造器可以被重载。
4,如果类中没有声明构造器,系统会自动添加一个没有参数的默认构造器。
5构造器是类创建时候系统调用的,因此多用于类的初始化。
最后说下一些在使用构造器中的注意事项。
1,构造器中一定不要创建自身的实例,否则会造成调用栈溢出错误。这个规则也适用于对象的实例变量,如果对象中有自身的引用,这个引用一定不能在定义中或者构造器中初始化。 class a { a _a = new a(); public a() { _a = new a(); a _b = new a(); } } 以上三种情况都会造成栈溢出,这样会造成一个无穷递归的调用栈。
2,如果父类是一个抽象类,那通过调用父类的构造器,也可以将它初始化,并且初始化其中的数据。
3,如果要在构造器中调用一个方法时,将该方法声明为private。 对于这个规则是需要一些说明的,假使你的父类构造器中要调用一个非静态方法,而这个方法不是private的又被子类所重载,这样在实际创建子类的过程中递归调用到了父类的构造器时,父类构造器对这个方法的调用就会由于多态而实际上调用了子类的方法,当这个子类方法需要用到子类中实例变量的时候,就会由于变量没有初始化而出现异常(至于为什么子类中的实例变量没有初始化可以参考上边的实例初始化过程),这是Java不想看到的情况。而当父类构造器中调用的方法是一个private方法时,多态就不会出现,也就不会出现父类构造器调用子类方法的情况,这样可以保证父类始终调用自己的方法,即使这个方法中调用了父类中的实例变量也不会出现变量未初始化的情况(变量初始化总是在当前类构造器主体执行之前进行)
练习:奥特曼打小怪兽和Boss
代码:/*********************OutMan***********************/
package cn.trainingcamp;
public class OutMan {
//定义名字和战斗力
private String name;
private int energy;
//设置属性:名字和战斗力
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setEnergy(int energy){
this.energy = energy;
}
public int getEnergy(){
return energy;
}
//设置行为:打boss
public void fight(Boss boss){
boss.setEnergy(boss.getEnergy()-1);
System.out.println(boss.getName()+"被"+name+"攻击了!\n"+boss.getName()+"剩余血量为"+boss.getEnergy());
}
//设置行为:打小怪兽
public void fight(Monster monster){
monster.setEnergy(monster.getEnergy()-2);
System.out.println(monster.getName()+"被"+name+"攻击了!\n"+monster.getName()+"剩余血量为"+monster.getEnergy());
}
}
/*********************Monster***************************/
package cn.trainingcamp;
public class Monster {
//定义名字和战斗力
private String name;
private int energy;
//设置属性:名字和战斗力
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setEnergy(int energy){
this.energy = energy;
}
public int getEnergy(){
return energy;
}
//设置行为:打OutMan
public void fight(OutMan outman){
outman.setEnergy(outman.getEnergy()-1);
System.out.println(outman.getName()+"被"+name+"攻击了!\n"+outman.getName()+"剩余血量为"+outman.getEnergy());
}
}
/***********************Boss*****************************/
package cn.trainingcamp;
public class Boss {
//定义名字和战斗力
private String name;
private int energy;
//设置属性:名字和战斗力
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setEnergy(int energy){
this.energy = energy;
}
public int getEnergy(){
return energy;
}
//设置行为:打OutMan
public void fight(OutMan outman){
outman.setEnergy(outman.getEnergy()-1);
System.out.println(outman.getName()+"被"+name+"攻击了!\n"+outman.getName()+"剩余血量为"+outman.getEnergy());
}
}
/**************************入口主函数*********************************/
package cn.trainingcamp;
public class SmallGame {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//实例化一个OutMan对象
OutMan outman = new OutMan();
outman.setName("奥特曼");
outman.setEnergy(100);
//实例化一个Boss对象
Boss boss = new Boss();
boss.setName("兽神");
boss.setEnergy(50);
//实例化一个Monster对象
Monster monster = new Monster();
monster.setName("小怪兽");
monster.setEnergy(40);
//战斗开始
System.out.println("====================战斗开始!=================\n");
while(outman.getEnergy() > 0 && monster.getEnergy()>0){
outman.fight(monster);
monster.fight(outman);
}
if(monster.getEnergy()<0 ){
System.out.println("战斗结束!\n"+outman.getName()+"胜利!");
}
if(outman.getEnergy()<0 ){
System.out.println("战斗结束!\n"+monster.getName()+"胜利!");
}
while(outman.getEnergy() > 0 && boss.getEnergy()>0){
outman.fight(boss);
monster.fight(outman);
}
if(boss.getEnergy()<0 ){
System.out.println("战斗结束!\n"+outman.getName()+"胜利!");
}
if(outman.getEnergy()<0 ){
System.out.println("战斗结束!\n"+boss.getName()+"胜利!");
}
}
}
相关推荐
网盘文件永久链接 目录 01 01-1MySQL介绍及索引... 02-4-4死锁.mp4 03 01mycat介绍及安装.mp4 02mycat分片配置.mp4 03mycat常用分片规则.mp4 04mycat读写分离.mp4 05-1分库分表介绍.mp4 05-2数据分片方案.mp4
政治总复习随堂集训-选修5专题4劳动就业与守法经营.docx
【标题】"2023小码王暑期集训-杭州营8月第一期-X02"揭示了这是一个关于编程教育的活动,特别是在2023年的暑假期间,由小码王组织,地点设在杭州,是8月份的第一期课程,编号为X02。这个标题暗示了该活动可能是一个...
2014政治总复习随堂集训-选修5专题4劳动就业与守法经营(精).pdf
2014高考政治必修3总复习随堂集训-第9课推动社会主义汇总.docx
2019高考二轮专题限时集训-书面表达之书信邮件 说明文(英语).docx
蓝桥杯大赛少儿创意编程组集训-难度一 本资源是蓝桥杯大赛少儿创意编程组集训的难度一课程,旨在使学员掌握EV3编程的基础知识和相关环境的基本使用。课程内容包括电脑和EV3主机基本操作、马达基础、传感器基础、...
《信奥帮-信息学奥赛-CSP-J1S1初赛集训知识点解析》 在信息技术日益发展的今天,信息学奥赛(IOI)已成为青少年展现编程技能和逻辑思维能力的重要舞台。CSP(Contest Selection Process)是NOIP(全国青少年信息学...
4. **国家集训队2014论文集.pdf**:展示了2014年集训队的研究成果,可对比历年论文,观察信息学竞赛的发展趋势。 5. **2022计算机考研专业课参考书目-修订版(2021年05月05日)D.pdf**:这份文档可能提供了2022年...
后台管理系统(供管理员使用): (1)登录、查看、修改个人信息(姓名、性别、年龄、学号/工号、联系方式等) (2)角色管理:分为管理员、老师、和学生三种角色 (3)用户管理:对用户进行添加、删除、修改、...……
emmmm,好好加油,相信你的数学建模会学的更好的,好好干,数学建模要多看论文,多看看往年的题目,emmmm,好好加油,相信你的数学建模会学的更好的,好好干,数学建模要多看论文,多看看往年的题目
4. 年份论文集差异:不同年份的论文集反映了信息学竞赛的发展历程和技术变迁。比如,2000年的论文可能更多涉及基础算法和编程语言的应用,而2017年的论文则可能涉及更高级的算法如近似算法、线性规划等,以及大数据...
第二章 DAS-4 第二章 DAS-5 第三章 NAS技术介绍-0 第三章 NAS技术介绍-1 第四章 SAN技术-0 第四章 SAN技术-1 第四章 SAN技术-2 第四章 SAN技术-3 第四章 SAN技术-4 第四章 SAN技术-5 第五章 RAID技术-0 ...
B树的高度通常保持在2-4之间,以减少I/O操作次数。 - **B+树**:与B树相比,B+树的叶子节点存储数据行的指针而不是实际数据。这种设计使得B+树在进行范围查询时更为高效。 综上所述,MySQL索引的合理设计与使用对于...
《国家集训队论文99-17.zip》是一个压缩包文件,包含了1999年至2014年期间,国家集训队的论文集合。这个资源对于研究计算机科学,特别是参与或关注ACM(国际计算机科学奥林匹克)竞赛的人来说极具价值。ACM竞赛是...
# 国家集训队论文列表(1999-2019) ___点击目录快速跳转:___ - _国家集训队论文列表(1999-2019)_ * [_1999_](#1999) * [_2000_](#2000) * [_2001_](#2001) * [_2002_](#2002) * [_2003_](#2003) * [_...
【国家集训队1999-2003】是一个涵盖了从1999年至2003年期间国家集训队相关活动的压缩包文件。这个文件集合可能包含了这段时间内国家集训队成员的研究成果、技术报告、竞赛资料或者学术论文等内容,旨在为学习者提供...
【标题】"2013国家集训队清华集训" 涉及的主要知识点是2013年中国国家信息学奥林匹克(OI)集训队在清华大学进行的训练活动。这个集训通常是为了选拔和准备国际信息学奥林匹克竞赛(IOI)的优秀学生团队。在这样的...
4. **编程语言与实践**:虽然论文主要关注算法和理论,但也会涉及编程实现,比如C++、Java或Python等语言的应用技巧,以及代码优化和调试方法。 5. **竞赛策略**:集训队经验分享中可能包含比赛策略,如何在有限...
《国家集训队2015-2018论文集》是一个压缩文件,其中包含了四年的中学生信息学竞赛——国际奥林匹克信息学竞赛(IOI)的国家集训队论文集。IOI是全球最高水平的信息学竞赛,旨在激发青少年对计算机科学的兴趣和潜能...