学习Java构造方法时候遇到的几个问题

一.什么是构造方法以及构造方法有什么用

构造方法是用于创建对象时初始化对象的一种方法,一个类可以有多个构造方法。

构造函数的主要作用是完成对象的初始化工作,(如果写的类里面没有构造函数,那么编译器会默认加上一个无参数且方法体为空的构造函数).它能够把定义对象时的参数传给对象的域。意即当创建一个对象时,这个对象就被初始化.如果这时构造函数不为空,则会在创建对象时就执行构造函数里面。

好处:通过重写函数可以直接给对象赋值,不用一个一个对着类里面参数去赋值了,简化代码。

package construct;

public class Constructor {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建两个对象p1,p2
//		President p1 = new President();
//		p1.name = "BaiDeng";
//		p1.age = 78;
//		
//		President p2 = new President();
//		p2.name = "TeLangpu";
//		p2.age = 74;
		
		
		President p1 = new President("BaiDeng",76); 
		President p2 = new President("TeLangpu",74);
		//直接打印这两个对象,会调用类本身的toString()方法
		//返回类名+@+hash码值
		//可以自己在类里面重写toString()方法,自己定义返回值
		System.out.println(p1);
		System.out.println(p2);

	}
	
	public static class President{
    
    //President(){} //可以不写,默认无参构造

	President(String name,int age){
		//构造函数,无参构造时可以不写
		
		this.name = name;
		this.age = age;
	}
	String name;
	int age;


	@Override
	//重写toString方法,重新定义President类的对象的输出格式
		public String toString() {
			return "{"+name+":"+age+"}";
		}
	}

}

从上述代码可以看出来:没有用构造方法时,创建p1,p2两个对象需要逐一赋值,但是有了有参数构造方法后,创建对象时只用重写构造方法就可以成功初始化对象。

另外注意的几点:

1.在函数的继承里,子类必须调用父类的构造函数。但是,子类只能继承父类的默认构造函数,如果父类没有默认的构造函数,那子类不能从父类继承默认构造函数.这时子类必须使用super来实现对父类的非默认构造函数的调用.​​​​​​。

2.构造函数的名称必须与类名相同,包括大小写。

3.构造函数没有返回值,不能用void修饰,一旦重写了构造函数,原先编译器默认的无参构造函数就会被覆盖,倘若加了返回值或修饰符,编译器会认为他是一个普通方法,编译时会因为找不到构造方法而报错。

二.如何输出对象的值

在调试时候想直接打印两个对象的值,最后结果是类名+@+变量(16进制)的hash值的字串。

查阅资料得知:由于所有java对象继承的是Object类,默认附带了一个toString()方法,直接打印其实就是只能得到对象的内存地址,也就是唯一标识。

//toString()方法的源码
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

所以在打印对象前,按照需要要重载toString()方法。

三.一个报错

大意是main函数里面的对象初始化时不能直接调用President类的构造方法。

有两种方法解决:

1.因为main函数是一个静态方法,不能直接调用非静态方法,所以简单的方法,把构造函数也定义成静态的。(代码就是第一张图)

至于为什么静态方法不能调用非静态方法:在一个类的静态成员中去访问非静态成员之所以会出错是因为在类的非静态成员不存在的时候静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。

后续会通过jvm和java的内存机制解释这个问题。

2.从报错这个层面解决。President类明显是个内部类,主函数里面p1,p2是President的实例化对象,由于主函数在内部类之外,所以实例化对象时候,要先实例化外部类,再实例化内部类。

最终代码:

package construct;

public class testConstruct {

	public static void main(String[] args) {//静态方法
		// TODO Auto-generated method stub
		
		//先实例化外部类,得到对象test1,test2,这两个对象都有new一个President类的对象的方法
		//注意内部类的实例化一定要先实例化外部类,顺序不能忘记
		testConstruct test1 = new testConstruct();
		President p1 = test1.new President("BaiDeng",78);
		
		testConstruct test2 = new testConstruct();
		President p2 = test2.new President("TeLangpu",74);
		
		System.out.println(p1);
		System.out.println(p2);

	}
	
	//President类,返回对象的姓名和年龄
	public class President{
		//动态构造方法
		President(String name,int age){
			//构造函数,无参构造时可以不写
			
			this.name = name;
			this.age = age;
		}
		String name;
		int age;
		
		@Override
		//重写toString方法,重新定义President类的对象的输出格式
			public String toString() {
			//把this.name和this.age传进去
				return "{"+name+":"+age+"}";
			}
		}
}

//输出:
//{BaiDeng:78}
//{TeLangpu:74}

最后,不断学习,不断积累和总结!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值