第九讲 构造方法

第九讲 构造方法

1 关于Set方法的补充

/*
	给成员属性设置值的时候,引进检查机制
*/

public class SetTest {
	
	private int age;
	public int num;
	public void setAge(int ageT) {
		if(ageT > 100 || ageT < 0) {
			System.out.println("年龄不合法!!");
			return;
		}
		age = ageT;
	}
	
	public int getAge() {
		return age;
	}
}


public class TestSet 
{
	public static void main(String[] args) 
	{
		SetTest st = new SetTest();
		st.num = 1000;// 这种方式很危险,只要别人能拿到这个对象,就能操作对象所有的属性。
		// 直接"."属性,毫不设限。只要拿到对象,想怎么改怎么改。
		st.setAge(20);// 这种方式也是一样的,别人也可以操作所有的属性。
		// 这个似乎也没有设限。我们来看看差别。
		st.setAge(1000); // 这样可以吗?人的年龄。
		st.setAge(-1000); // 这样可以吗?人的年龄。
		System.out.println(st.getAge()); // 结果是多少?
	}
}

关于private
	在同一个类中,private修饰的方法是可以被其他方法调用的。但是如果要在其他类中调用另一个类中的private修饰的成员方法,则编译不通过。这也说明,private是私有的,只属于定义该方法的类的对象所有。
public class PrivateTest 
{	
	private int id;
	private void test() {
		System.out.println("0.00.0.0.0.0.0.00");
	}

	public static void main(String[] args) {
		PrivateTest pt = new PrivateTest();
		pt.test(); // 这样呢?可以
		System.out.println(pt.id);// 这样可以吗?可以
	}
}

public class Test01
{
	public static void main(String[] args) 
	{
		PrivateTest pt = new PrivateTest();
		pt.test(); // 这会有什么结果?编译报错
		// Test01.java:6: 错误: test() 在 PrivateTest 中是 private 访问控制
        //        pt.test();
	}
}


2 构造方法

类是一个抽象的概念,类中有成员方法和成员属性。成员属性是该类共有的属性描述,成员方法是该类共有的行为描述。类需要我们抽象出来,抽象的依据就是这一类事物的共性。比如说:人类,那么就应该抽象人类的共性,不能把动物的一些特有的属性放进来。成员也一样。
对象,是类的实例,我们定义好类以后,就需要产生对象,否则类没有意义。
如何生成对象?
	类名 引用变量名 = new 类名();
	比如人类:Person person = new Person();
	标识符();这种方式一般都是方法。我说的是一般情况下,有特殊情况,这个以后再说。
	那么:Person(),这就是一个方法。
	上节课我们说过:new Person();只要这个语句被执行,就会在堆内存中产生对象。
	new是一个关键字,也是一个运算符。
	要生成对象,就要有一个可以生产对象的地方,在java中只存在两个部分的内容,一个是成员属性,一个是成员方法。那么生成对象,产生对象,是一个动作,是一个业务逻辑,是一种行为。那么对象肯定是在方法中产生。
	产生对象的方法叫做构造方法,也叫作构造器。"Constructor"
public class Constructor01 
{
	private int id;
	private String name;

	public int getId() {
		return id;
	}
	public void setId(int cid) {
		id = cid;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String cName) {
		name = cName;
	}
}

public class Test01
{
	public static void main(String[] args) 
	{
		Constructor01 c01 = new Constructor01();
		c01.setId(100);
		System.out.println(c01.getId()); // result ---> 100
	}
}
// new 关键字也叫作运算符,他与+-*/差不多。
// Constructor01();这个方法有被定义过吗?没有被定义它是怎么被调用的?
// java有这么神奇,没有被定义的方法居然可以无中生有吗?肯定不可以。
// 我们确实没有定义过Constructor01()方法,但是它一定是被定义了的,这个方法是系统默认的
// 这叫做默认构造方法。
# 关于构造方法: 
	如果我们没有写任何的构造方法,系统会默认提供一个无参的构造器。
	我们来看看当前我们知道的构造器是系统默认的无参数的:
		Constructor01();
		这个方法名,与类名一样。-------- (1)
	这个方法有返回值吗?
    	有 / 没有
    这个方法有什么用?
    	1) new Constructor01()这个被执行的时候,会在堆内存中开辟一块空间,用来存放具体的对象,给对象的成员属性赋初值,赋默认值。
    	2) 如果,我们写了有参数的构造器,那么执行完构造方法后,对象的成员属性就会被赋值。
    	

在这里插入图片描述

public Constructor01() {
		
}
public Constructor01(int cid, String cName) {
	id = cid;
	name = cName;
}

以上是构造方法的写法,分析一下该方法的定义:
    1.方法名和类名一致
    2.方法没有返回值类型
    3.它可以有参数,也可以没有参数,是一个重载了的方法
    4.它的参数个数最少0个,最多只能是成员属性的个数。如果超出了成员属性参数个数的范围,编译报错。
    5.它的参数列表中的形参类型一定要和成员属性的参数类型匹配。否则编译报错。
 
构造方法的作用:
    1.在堆内存中生成对象
    2.给对象的成员属性赋初始值
    3.如果是无参的构造,那么成员属性被赋默认值(基础数据类型的默认值是什么样的?(课后自己去测)。引用数据类型的初始值是什么样的?---null)
    4.只有构造器被执行以后,才会生成对象。所它极其重要。

一个神奇的现象:
    代码如下:我们定义了一个有参的构造器,没有写无参的构造器。
public class Constructor01 
{
	private int id;
	private String name;

	//public Constructor01() {	
	//}
	public Constructor01(int cid, String cName) {
		id = cid;
		name = cName;
	}
	
	public Constructor01(int cid) {
		id = cid;
	}

	public int getId() {
		return id;
	}
	public void setId(int cid) {
		id = cid;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String cName) {
		name = cName;
	}

	public String toString() {
		return "{" + id + ", " + name + "}";
	}
}
// ---------------------调用--------------
public class Test01
{
	public static void main(String[] args) 
	{
		Constructor01 c01 = new Constructor01(); // 这样做可以吗?
        /*
        	E:\java基础\day05-1>javac Test01.java
            Test01.java:5: 错误: 对于Constructor01(没有参数), 找不到合适的构造器
                            Constructor01 c01 = new Constructor01();
                                                ^
                构造器 Constructor01.Constructor01(int,String)不适用
                  (实际参数列表和形式参数列表长度不同)
                构造器 Constructor01.Constructor01(int)不适用
                  (实际参数列表和形式参数列表长度不同)
            1 个错误
        */
		Constructor01 c02 = new Constructor01(1, "zhangsan");
		Constructor01 c03 = new Constructor01(122);
		System.out.println(c01); 
		System.out.println(c02);
		System.out.println(c03);// {122, null}
/*
		E:\java基础\day05-1>java Test01
		{0, null}
		{1, zhangsan}
*/
	}
}

E:\java基础\day05-1>javac Test01.java
Test01.java:5: 错误: 对于Constructor01(没有参数), 找不到合适的构造器
                Constructor01 c01 = new Constructor01();
                                    ^
    构造器 Constructor01.Constructor01(int,String)不适用
      (实际参数列表和形式参数列表长度不同)
    构造器 Constructor01.Constructor01(int)不适用
      (实际参数列表和形式参数列表长度不同)
1 个错误

构造方法是一个重载的方法,如果我们在类中没有定义构造方法,系统会默认有一个没有参数也叫作无参构造。
如果,我们定义了一个有参的构造方法,没有定义无参的构造方法,那么系统不再给默认的无参构造。编译的时候,系统会屏蔽掉无参的默认构造,只会去找我们定义的有参构造。
记住:如果我们没有手动定义无参构造,而又定义了其他有参构造,系统将不会再给出默认的无参构造。无参就不会存在,我们也不能在代码中使用该无参构造。
记住:正常情况下,我们都需要定义无参构造,然后再定义自己想要的有参构造。(Overload)
只要满足构造方法的定义条件(参数列表中参数的个数最多不能超过成员属性的个数,而且类型要匹配),无论你定义多少个构造,都是可以的,只要满足方法的重载机制。

在java中要构造对象,必须满足两个条件:
	1. 要有构造器
	2. 要使用 new 运算符

注意:
	我们在定义构造方法的时候,不需要全部定义所有的可能的构造方法,我们定义的时候,根据我们的需求来进行。
// 一个奇怪的现象:一下代码会有造成什么问题?
public class Constructor02 
{
	private int id;
	private Constructor02(int cid) {
		id = cid;
	}
}
// 这个代码说明:在其他类中无法生成对象,因为private修饰的方法不能在其他类中被调用。
// 这样做有用吗?有用,有什么用?
// 我想要在其他类中获得Constructor02类型的对象该怎么做?
public class Constructor02 
{
	private int id;
	private Constructor02(int cid) {
		id = cid;
	}
    public Constructor02 instance() {
        return new Construcotr02();
    }
}
补充的内容:
public class Test03 
{
	private int id;
/*
	public Test03(int id) {
		id = id; // 就近原则
	}
*/
	public Test03(int id) {
		this.id = id;
	}
	public static void main(String[] args) {
		Test03 t = new Test03(10);
		System.out.println(t.id); // 请问成员属性id的值是多少?0 
		// java中有个原则,叫做"就近原则" 形参中的id和构造方法中的两个id是同一个
		// 这样做编译没有问题,但是执行会得不到想要的结果。
		// 怎么办?----> this关键字
		
	}
	
}

补充内容:单例singleton
public class Constructor02 
{
	private int id;
	private Constructor02(int cid) {
		id = cid;
	}

	private static Constructor02 cc = new Constructor02(100);
	public static Constructor02 instance() {
		return cc;
	}

	public int getId() {
		return id;
	}
}
涉及到static关键字
public class Test01
{
	public static void main(String[] args) 
	{
		Constructor02 cc = Constructor02.instance();
		System.out.println(cc);// Constructor02@e9e54c2
		Constructor02 cc1 = Constructor02.instance();
		System.out.println(cc1);// Constructor02@e9e54c2
		Constructor02 cc2 = Constructor02.instance();
		System.out.println(cc2);// Constructor02@e9e54c2
		Constructor02 cc3 = Constructor02.instance();
		System.out.println(cc3);// Constructor02@e9e54c2
		
	}
}
    
构造方法的重载
public class Constructor01 
{
	private int id;
	private String name;

	public Constructor01() {	
	}
	public Constructor01(int cid, String cName) {
		id = cid;
		name = cName;
	}
	public Constructor01(String cName, int cid) {
		id = cid;
		name = cName;
	}
	public Constructor01(String cName) {
		name = cName;
	}
	public Constructor01(int cid) {
		id = cid;
	}

	public int getId() {
		return id;
	}
	public void setId(int cid) {
		id = cid;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String cName) {
		name = cName;
	}

	public String toString() {
		return "{" + id + ", " + name + "}";
	}
}

public class Test01
{
	public static void main(String[] args) 
	{
		Constructor01 c01 = new Constructor01();
		Constructor01 c02 = new Constructor01(1, "zhangsan");
		Constructor01 c03 = new Constructor01(122);
		Constructor01 c04 = new Constructor01("lisi");
		Constructor01 c05 = new Constructor01("wus", 200);
		System.out.println(c01); 
		System.out.println(c02);
		System.out.println(c03);// {122, null}
		System.out.println(c04);
		System.out.println(c05);
/*
		E:\java基础\day05-1>java Test01
		{0, null}
		{1, zhangsan}
*/
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值