首先,构造器是类中进行说明的特殊的成员方法,构造器的作用是在创建对象时,系统自动调用它来给所创建的对象初始化。此时问题又出来了,为什么不直接初始化对象就好,还要使用一个构造器呢,这不是很多余,其实不然。
当没有定义构造器时每个类里都有一个默认的无参的构造方法,此时该类就只有一个构造器;而当你显示定义类的构造器时,那就没有那个默认的构造方法了,该类所有的构造器就是你已经定义了的那些构造器;
例如:定义一个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()+"胜利!");
}
}
}
相关推荐
蓝桥杯大赛少儿创意编程组集训-难度一
2023小码王暑期集训-杭州营8月第一期-X02
网盘文件永久链接 目录 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
2014政治总复习随堂集训-选修5专题4劳动就业与守法经营(精).pdf
2014高考政治必修3总复习随堂集训-第9课推动社会主义汇总.docx
2019高考二轮专题限时集训-书面表达之书信邮件 说明文(英语).docx
信奥帮-信息学奥赛-CSP-J1S1初赛集训知识点-考点-思维导图课件
7天实战集训营-带你锤碎MySQL(1).pdf
后台管理系统(供管理员使用): (1)登录、查看、修改个人信息(姓名、性别、年龄、学号/工号、联系方式等) (2)角色管理:分为管理员、老师、和学生三种角色 (3)用户管理:对用户进行添加、删除、修改、...……
NOIP国家集训队论文集 1999-2009 2013 2015 2017 2014 2015 NOI 冬令营ppt
emmmm,好好加油,相信你的数学建模会学的更好的,好好干,数学建模要多看论文,多看看往年的题目,emmmm,好好加油,相信你的数学建模会学的更好的,好好干,数学建模要多看论文,多看看往年的题目
Scratch组集训教程包-180901 Scratch组集训教程包-180901 Scratch组集训教程包-180901
618会员运营集训营-淘宝商家平台.pdf
C语言集训营-C语言集训营1期的代码和板书
# 国家集训队论文列表(1999-2019) ___点击目录快速跳转:___ - _国家集训队论文列表(1999-2019)_ * [_1999_](#1999) * [_2000_](#2000) * [_2001_](#2001) * [_2002_](#2002) * [_2003_](#2003) * [_...
国家集训队论文集1999~2014,99-09,13-14,17,总共14年的论文
信奥帮初赛集训配套课件,首发!!! PART2-CSP(NOIP)信息学奥赛初赛集训 程序设计基础知识
包括IOI中国国家集训队从1999年到2017年的论文 部分目录: 国家集训队1999论文集 陈宏:《数据结构的选择与算法效率——从IOI98试题PICTURE谈起》 来煜坤:《把握本质,灵活运用——动态规划的深入探讨》 齐鑫:...
IOI国家集训队论文1999-2021(缺2020)-2021.08.03.rar