面向对象基础——构造方法私有化、对象数组、内部类

构造方法私有化

类的封装性不光体现在对属性的封装上,实际上方法也是可以被封装的,当然,在方法封装上也包含了对构造方法的封装。例如如下代码就是对构造方法封装。
class Singleton{
	private Singleton(){		// 将构造方法进行了封装,私有化	
	}
	public void print(){
		System.out.println("Hello World!!!") ;
	}
};

使用
class Singleton{
	private Singleton(){		// 将构造方法进行了封装,私有化	
	}
	public void print(){
		System.out.println("Hello World!!!") ;
	}
};
public class SingletonDemo02{
	public static void main(String args[]){
		Singleton s1 = null ;	// 声明对象
		s1 = new Singleton() ;	// 错误,无法实例化对象
	}
};

此时,被私有化构造方法的Singleton类,不能在外部实例化,但是可以在内部实例化,如下所示:
class Singleton{
	Singleton instance = new Singleton() ;	// 在内部产生本类的实例化对象
	private Singleton(){		// 将构造方法进行了封装,私有化	
	}
	public void print(){
		System.out.println("Hello World!!!") ;
	}
};
public class SingletonDemo03{
	public static void main(String args[]){
		Singleton s1 = null ;	// 声明对象
	}
};

一个类的构造方法被私有化之后,则只能从其类的内部取得实例化对象,那么此时考虑的问题就是如何把内部生成的instance对象拿到外部类,这样外部就可以直接通过此对象进行实例化。
正常情况下,instance属性只能通过Singleton类的实例化对象才可以进行调用,如果在没有实例化对象的时候依然可以取得instance对象,则就需要将instance声明成static访问类型,因为使用static声明的变量,可以直接使用类名进行访问。如下所示:
class Singleton{
	static Singleton instance = new Singleton() ;	// 在内部产生本类的实例化对象
	private Singleton(){		// 将构造方法进行了封装,私有化	
	}
	public void print(){
		System.out.println("Hello World!!!") ;
	}
};
public class SingletonDemo04{
	public static void main(String args[]){
		Singleton s1 = null ;	// 声明对象
		s1 = Singleton.instance ;	// 取得实例化对象
		s1.print() ;		// 调用方法
	}
};
正常情况下,这些属性应该封装起来,所以以上代码最好修改为以下形式:
class Singleton{
	private static Singleton instance = new Singleton() ;	// 在内部产生本类的实例化对象
	public static Singleton getInstance(){		// 通过静态方法取得instance对象
		return instance ;
	}
	private Singleton(){		// 将构造方法进行了封装,私有化	
	}
	public void print(){
		System.out.println("Hello World!!!") ;
	}
};
public class SingletonDemo05{
	public static void main(String args[]){
		Singleton s1 = null ;	// 声明对象
		s1 = Singleton.getInstance() ;	// 取得实例化对象
		s1.print() ;		// 调用方法
	}
};
构造方法私有化之后,就可以通过以上的形式取得实例化对象。
程序的意义在于:将构造方法私有化防止外部生成对象,只能通过静态方法获得第一次初始化且是唯一的单例对象。

对象数组

所谓的对象数组,就是指包含了一组相关的对象,但是在对象数组的使用中一定要注意:数组一定要先开辟空间,但是因为其是引用数据类型,所以数组里的每一个对象都是null值,则在使用的时候数组中的每一个对象必须分别进行实例化操作。
对象数组的声明
类 对象数组名称[] = new 类[数组长度];
class Person{
	private String name ;		// 姓名属性
	public Person(String name){	// 通过构造方法设置内容
		this.name = name ;		// 为姓名赋值
	}
	public String getName(){
		return this.name ;		// 取得姓名
	}
};
public class ObjectArrayDemo01{
	public static void main(String args[]){
		// 类名称 数组名称[] = new 类名称[长度]
		Person per[] = new Person[3] ;	// 开辟了三个空间大小的数组
		System.out.println("============== 数组声明 =================") ;
		// 对象数组初始化之前,每一个元素都是默认值
		for(int x=0;x<per.length;x++){	// 循环输出
			System.out.print(per[x] + "、") ;	// 因为只是开辟好了空间,所以都是默认值
		}
		// 分别为数组中的每个元素初始化,每一个都是对象,都需要单独实例化	
		per[0] = new Person("张三") ;	// 实例化第一个元素
		per[1] = new Person("李四") ;	// 实例化第二个元素
		per[2] = new Person("王五") ;	// 实例化第三个元素
		System.out.println("\n============== 对象实例化 =================") ;
		for(int x=0;x<per.length;x++){	// 循环输出
			System.out.print(per[x].getName() + "、") ;	// 此时,已经实例化完成了,所以会直接打印出姓名
		}
	}
};


数组在使用的时候也分为静态初始化和动态初始化。如下所示:

class Person{
	private String name ;		// 姓名属性
	public Person(String name){	// 通过构造方法设置内容
		this.name = name ;		// 为姓名赋值
	}
	public String getName(){
		return this.name ;		// 取得姓名
	}
};
public class ObjectArrayDemo02{
	public static void main(String args[]){
		// 声明一个对象数组,里面有三个对象,使用静态初始化方式完成
		Person per[] = {new Person("张三"),new Person("李四"),new Person("王五")} ;
		System.out.println("\n============== 数组输出 =================") ;
		for(int x=0;x<per.length;x++){	// 循环输出
			System.out.print(per[x].getName() + "、") ;	// 此时,已经实例化完成了,所以会直接打印出姓名
		}
	}
};



注意:对象数组中的每个元素都必须单独实例化,否则内容就为null。

内部类

在一个类的内部还存在另外一个类,则称为内部类。
在类内部也可以定义另外一个类。如果在类Outer的内部再定义一个类Inner,此时Inner就称为内部类,而类Outer则称为外部类。
内部类可声明成public或private。当内部类声明成public或private时,对其访问的限制与成员变量和成员方法完全相同。内部类的定义格式如下:

class Outer{		// 定义外部类
	private String info = "hello world" ;	// 定义外部类的私有属性
	class Inner{	// 定义内部类
		public void print(){				// 定义内部类的方法
			System.out.println(info) ;		// 直接访问外部类的私有属性
		}
	};
	public void fun(){						// 定义外部类的方法
		new Inner().print() ;				// 通过内部类的实例化对象调用方法
	}
};
public class InnerClassDemo01{
	public static void main(String args[]){
		new Outer().fun() ;					// 调用外部类的fun()方法
	}
};

以上程序中,Inner类作为Outer类的内部类存在,并且在外部类fun()方法之中直接实例化内部类的对象并调用print()方法。
内部类存在的特点:
缺点:正常一个类操作时,在类中最好只定义属性和方法,如果再定义一个类的话,则肯定破坏了类的结构。
优点:可以实现两个类之间的数据访问,内部类可以访问外部类的属性。拆分类验证如下:

class Outer{		// 定义外部类
	private String info = "hello world" ;	// 定义外部类的私有属性
	public void fun(){						// 定义外部类的方法
		new Inner(this).print() ;				// 通过内部类的实例化对象调用方法
	}
	public String getInfo(){				// 增加了一个getter方法取得info内容
		return this.info ;	
	}
};
class Inner{	// 定义内部类
	private Outer out = null ;				// 声明Outer对象
	public Inner(Outer out){
		this.out = out ;
	}
	public void print(){				// 定义内部类的方法
		System.out.println(this.out.getInfo()) ;		// 直接访问外部类的私有属性
	}
};
public class InnerClassDemo02{
	public static void main(String args[]){
		new Outer().fun() ;					// 调用外部类的fun()方法
	}
};
如果将内部类拿到外部之后,会发现代码增加了,而且复杂度增加了。使用内部类的最大优点,可以方便的访问外部类中的私有属性。但是,以上的内部类,是无法在外部直接调用的,是无法按照外部类的形式使用的。
使用static声明内部类
如果一个内部类使用static关键字声明,则此内部类就称为外部类,可以直接通过外部类.内部类进行访问。
class Outer{		// 定义外部类
	private static String info = "hello world" ;	// 定义外部类的私有属性
	static class Inner{	// 使用static定义内部类为外部类
		public void print(){				// 定义内部类的方法
			System.out.println(info) ;		// 直接访问外部类的私有属性
		}
	};
	public void fun(){						// 定义外部类的方法
		new Inner().print() ;				// 通过内部类的实例化对象调用方法
	}
};
public class InnerClassDemo03{
	public static void main(String args[]){
		new Outer.Inner().print() ;					// 调用外部类的fun()方法
	}
};

使用static可以声明一个内部类,声明的内部类就称为外部类,可以在类的外部调用,但是如果想访问外部类的属性,则此属性必须是static访问权限的。
在外部类访问内部类:
一个内部类除了可以通过外部类访问,也可以直接在其他类中调用,但是调用的格式必须是:
外部类.内部类 内部类对象 = 外部类实例.new 内部类();
class Outer{		// 定义外部类
	private String info = "hello world" ;	// 定义外部类的私有属性
	class Inner{	// 定义内部类
		public void print(){				// 定义内部类的方法
			System.out.println(info) ;		// 直接访问外部类的私有属性
		}
	};
	public void fun(){						// 定义外部类的方法
		new Inner().print() ;				// 通过内部类的实例化对象调用方法
	}
};
public class InnerClassDemo04{
	public static void main(String args[]){
		Outer out = new Outer()	;			// 外部类实例化对象
		Outer.Inner in = out.new Inner() ;	// 实例化内部类对象
		in.print() ;						// 调用内部类的方法
	}
};

还可以在方法中定义内部类
一个类可以在任意位置上定义,如下所示 可以在方法内定义内部类。但是内部类所在方法的参数必须定义成final类型。
class Outer{		// 定义外部类
	private String info = "hello world" ;	// 定义外部类的私有属性
	public void fun(final int temp){		// 定义外部类的方法
		class Inner{						// 在方法中定义的内部类
			public void print(){				// 定义内部类的方法
				System.out.println("类中的属性:" + info) ;		// 直接访问外部类的私有属性
				System.out.println("方法中的参数:" + temp) ;
			}
		};
		new Inner().print() ;				// 通过内部类的实例化对象调用方法
	}
};
public class InnerClassDemo05{
	public static void main(String args[]){
		new Outer().fun(30) ;	// 调用外部类的方法
	}
};


总结:内部类在实际的开发中非常有用。如果使用static声明内部类的情况下,切记,使用static声明的内部类是外部类,操作的时候要使用 “外部类.内部类”的形式访问。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值