面向对象基础续2(static关键字、理解main方法、代码块、构造方法私有化(单例模式)) .

static关键字

如果现在希望一个属性被所有对象所共同拥有,则可以将其声明为static类型,声明static类型的属性或方法之后此属性或方法也成为类方法,可以由类型直接调用。

使用static声明属性

使用static声明的属性被称为全局变量,是所有对象共享的,简单来说就是在一个对象中改变了此全局属性,则其他对象中的属性也会改变,代码如下:

class Person
{
	String name;
	int age;
	static String country="A城";	//使用static声明全局变量
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public void getInfo(){
		System.out.println("姓名是:"+name+"年龄是:"+age+"城市是:"+country);
	}
}
public class staticDemo01
{
	public static void main(String args[]){
		Person per1=new Person("张三",20);
		Person per2=new Person("李四",40);
		Person per3=new Person("王五",30);
		per1.getInfo();
		per2.getInfo();
		per3.getInfo();
		System.out.println("---------修改之前-----------");
        //在静态的方法中只能调用静态的属性
		Person.country="B城";	//只有当country属性为static时才能够调用,否则会出现无法从静态上下文中引用非静态的变量的错误
		per1.getInfo();
		per2.getInfo();
		per3.getInfo();
		System.out.println("---------修改之前-----------");
	}
}

每一个对象都拥有各自的堆栈空间,堆内存空间中保存每个对象的各自的属性,但是所有的使用static关键字声明的属性是保存在了全局数据区之中,所有的对象指向全局数据区域中的一个内容,所有当一个对象修改了此属性之后,所有的对象的内容都会发生变化。

Java中的内存区域:

·栈内存:可以保存对象的名称,(保存,访问的堆内存的地址)

·堆内存:保存每个对象的具体属性。

·全局数据区:保存static类型的属性。

·全局代码区:保存所有方法的定义。

声明static方法

如果一个方法使用了static关键字声明,则此方法可以由类名称直接调用,即:类名称.方法

class Person
{
	static String name="张三";
	static int age=20;
	static String country="A城";	//使用static声明全局变量
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public static void getInfo(){
		System.out.println("姓名是:"+name+"年龄是:"+age+"城市是:"+country);
	}
}
public class staticDemo02
{
	public static void main(String args[]){
		Person.getInfo();
	}
}

注意:使用static声明的方法,不能调用非static的属性或方法。就是说假如以上代码中Person类中name和age属性没有声明为static类型,则会出现错误。原因是因为static属性或方法可以在对象没有被实例化之前就可以调用了。

static的其它应用

统计一个类中到底有多少个类被实例化:

class Person
{
	static int count=0;
	public Person(){
		count++;   //只要有一个对象产生就自增
		System.out.println("有"+count+"个对象被实例化了!");
	}
}
public class staticDemo03
{
	public static void main(String args[]){
		new Person();     //1
		new Person();     //2
		new Person();     //3
	}
}

自动编名操作:

class Person
{	
	String name;
	private static int count=0;
	
	public Person(String name){
		count++;
		this.name="DEMO-"+count;
	}
	public void getName(){
		System.out.println("姓名是:"+name);
	}
}
public class staticDemo04
{
	public static void main(String args[]){
		new Person("").getName();   //DEMO-1
		new Person("").getName();   //DEMO-2
		new Person("").getName();   //DEMO-3
	}
}

以上应用在以后的开发中会有所实现。

理解main方法

具体内容

解释:public static void main(String args[ ])

public:表示此方法可以被外部调用。

static:表示此方法可以由类名称直接调用。

void :主方法是程序的起点,所以不需要任何的返回值。

main:系统规定好默认调用的方法名称,执行的时候,默认找到main方法名称。

String args[ ] 表示的是运行时的参数,参数传递的形式:java类名称 参数1参数2参数3

看如下的代码:

public class staticDemo05
{
	public static void main(String args[]){
		for(String x:args){
			System.out.println(x);
		}
	}
}

该代码在执行时必须传入参数,格式:java类名称 参数1 参数2参数3….参数个数不限,但必须用“ ”(空格)隔开,输出为输入的内容。

代码2:对传入的参数进行判断:

public class staticDemo06
{
	public static void main(String args[]){
		if(args.length!=3){
			System.out.println("参数格式不正确,程序退出!");
			System.exit(1);
		}
		for(String x:args){
			System.out.println(x);
		}
	}
}

参数个数不是3,程序将自动退出。

代码块

所谓的代码块是指使用“{ }”括起来的一段代码,根据位置不同,代码块可以分为四种:普通代码块、构造块、静态代码块、同步代码块。

普通代码块

直接定义在方法中的代码称为普通代码块:

public class codeDemo01
{
	public static void main(String args[]){
		{
			//普通代码块
			int x=30;	//属于一个局部变量
			System.out.println("普通代码块-----> x ="+x);
		}
		int x=100;		//与局部变量名称相同 想对来说就成了全局变量
		System.out.println("普通代码块之外-----> x ="+x);
	}
}

构造块:

将代码块直接定义在类中,则称为构造块。构造块的内容会优先于构造方法的执行,且执行多次,当有实例化对象的时候执行

class Demo
{
	{
		//构造块
		System.out.println("构造块");
	}
	public Demo(){
		System.out.println("构造方法");
	}
}
public class codeDemo02{
	public static void main(String args[]){
		new Demo();	//实例化对象
		new Demo(); //实例化对象 
		new Demo(); //实例化对象
	}
}

静态代码块

直接使用static关键字声明的代码就称为静态代码块。

class Demo
{
	{
		//构造块
		System.out.println("构造块");
	}
	static{
		System.out.println("Person中的静态代码块");
	}
	public Demo(){
		System.out.println("构造方法");
	}
}
public class codeDemo03{
	static{
			System.out.println("MAIN方法中的静态代码块");
		}
	public static void main(String args[]){
		
		new Demo();	//实例化对象
		new Demo(); //实例化对象 
		new Demo(); //实例化对象
	}
}

如果主方法中存在静态代码块,则静态块优先于主方法的执行,如果是在普通的类中定义的代码块,优先于构造方法执行,不管有多少个实例化对象产生,静态代码块只执行一次,静态代码块的主要功能是为静态属性初始化值。

构造方法私有化(单例模式)

类的封装性不单单是体现在对属性的封装上,方法也是可以封装的,当然,在方法中也包含了对构造方法的封装,例如如下代码:

class Singleton
{
	private Singleton(){	//使用private 私有化当前构造方法
		System.out.println("对象被实例化了");
	}
}
public class SingletonDemo01
{
	public static void main(String args[]){
		Singleton sin=null;
		sin=new Singleton();	//出现错误,不能实例化
	}
}

此时的解决办法是在Singleton类内部进行实例化,然后定义为static这样在类的外部可以直接用类名.属性直接访问。代码如下:

class Singleton
{
	static Singleton instance=new Singleton();
	private Singleton(){	//使用private 私有化当前构造方法
		System.out.println("对象被实例化了");
	}
}
public class SingletonDemo02
{
	public static void main(String args[]){
		Singleton sin=null;
		sin=Singleton.instance;	//程序输出对象被实例化了
	}
}

但是以上的代码设计不是最合理的,最完美的写法:即(单例设计模式)

饿汉式单例模式:

class Singleton
{   //进来就进行实例化的饿汉
	private static Singleton instance=new Singleton();	//私有化当前对象
	private Singleton(){	//使用private 私有化当前构造方法
		System.out.println("对象被实例化了");
	}
	public static Singleton getInstance(){	//通过方法获得当前类实例化好的对象
		return instance;
	}
}
public class SingletonDemo03
{
	public static void main(String args[]){
		Singleton sin=null;
		sin=Singleton.getInstance();	//程序输出对象被实例化了
	}
}

懒汉式单例设计模式

class Singleton
{   //在方法中进行实例化的是懒汉
	private static Singleton instance=null;	//声明并私有化当前对象
	private Singleton(){	//使用private 私有化当前构造方法
		System.out.println("对象被实例化了");
	}
	public static Singleton getInstance(){	//通过方法获得当前类实例化好的对象
		instance=new Singleton();
		return instance;
	}
}
public class SingletonDemo04
{
	public static void main(String args[]){
		Singleton sin=null;
		sin=Singleton.getInstance();	//程序输出对象被实例化了
	}
}

使用单例设计模式的好处:

不管当前程序有多少个new关键字,假如要想得到Singleton类的对象,就必须要调用其getinstance方法,所以只会有一个实例被创建,而所有的对象都是隶属于该实例。现在了过多的对象被创建。其核心就是构造方法的私有化。

你可能感兴趣的:(面向对象基础续2(static关键字、理解main方法、代码块、构造方法私有化(单例模式)) .)