JAVA 类的高级概念

2016-04-22 1334点热度 0条评论

访问修饰符

每一个成员(成员变量、方法和构造器)都有一个访问修饰符,用来判断谁可以访问该成员。

本类 同包类 不同包类
子类 非子类 子类 非子类
public
protected
默认修饰符
private

封装的概念及好处

  1. 组装(定义一个类就是封装)
    类的定义:1、属性  2、行为
  2. 信息隐藏
    • 访问修饰符
      Public、Pprotected、默认、Private
    • 方法实现调用者无需知道方法的具体步骤,只关心效果(功能)的达成
    • 访问器、修改器(get、set方法)
  3. 封装的好处
    • 类的成员变量可以成为只读或者只写的提供的方法可以根据自己的意义来是否提供给使用者
    • 类可以对存储在其成员变量中的内容有一个整体的控制可以对用户传进来的参数进行判断是否符合要求,在接口处把控
    • 类的用户不需要知道类是如何存储数据的
  4. 类的任何一个方法都是封装性的体现

Static关键字

  1. 凡是使用Static修饰的,都与对象无关,与类有关
  2. 凡是使用Static修饰的,都是优先加载的(JVM加载的时候就开始加载);
  3. 构造方法是不能使用Static修饰的(因为构造是在JVM加载后执行的动作)

属性:

  1. 类属性
    • 全类共享一个值(一处更改全类改变)
    • 存在于数据段的静态区,JVM加载期既放入
    • 常量属性直接用Static
    • 变量属性一定要分析出全类共享一个值才能使用
  2. 方法(又被称之为类方法)
    • 方法中只能操作Static修饰的属性或方法
    • 工具类的工具方法一般设置成Static(不改变属性值,只做处理操作)
  3. 初始化块
    1. 静态初始化块:
      • 在类加载期被执行,仅执行一次(因为加载是只做一次的)
      • 可以在类准备期间书写一些准备工作的代码,所以经常使用
      • 使用频率常常比静态方法和静态属性高;
    2. 实例初始化块:
      • 在产生对象的时候执行,可以被执行多次。
      • 在本类构造之前,在父类构造之后执行
      • 很少使用,功能与构造方法重合

静态类成员(方法)别名:类方法

  1. Static修饰的方法:可以直接用类进行调用。与对象无关,属于类级别;
  2. Static修饰的方法和属性在加载期会被优先加载;Static的方法不能操作费Static的属性和其他方法

使用范围:

  1. 工具类的工具方法设置为Static
  2. Static 修饰的方法叫静态方法,即类方法
    Static修饰过的方法属于类方法,它不属于这个类的实例(对象),因此在static修饰的方法中为变量赋值就会报错,因为我们内存中根本就还没有该变量。
  3. 类方法只能使用静态变量

访问方法:不用创建对象,直接使用   类名.属性

  1. 静态方法不能访问变量
  2. 非静态方法可以访问静态属性和变量

代码块(初始化块)

除了声明静态成员变量和方法外,关键字Static还有另外一种方法。java类可以包含一个静态初始化块,静态初始化块是一组当类被jvm的类加载器加载时执行的语句。

  1.  静态初始化块
    在类加载的时候被自动执行,执行在main方法之前,只执行一次;
  2.  实例初始化块
    在产生对象的时候执行,可以被执行多次。
static {
	System.out.print("这是一个静态代码块,它在JVM加载时执行");
}

{
	System.out.print("这是一个实例代码块,它在实例化对象的时候执行");
}

概述:

  • 在一个类的内部重新定义一个新的类
  • 内部类也是一个完整的、独立的类。
  • 可以有属性、方法、构造、代码块,同样可以产生对象
  • 编译后有自己独立的class文件(Java文件的Class名字与类名无关,除非是public
  • 在外部类的内部,可以产生成员内部类的对象
  • 成员内部类名字是: 外部类名字$内部类名字.class
  • 局部内部类名字是: 外部类名字$数字内部类名字.class
  • 匿名内部类名字是: 外部类名字$数字.class

分类:

  1. 成员内部类
    • 作为类的成员,存在于某个类的内部
    • 与静态内部类不同的是,inner类定义的时候没有static关键词,所以它必须在外部类被实例化之后才能使用inner类的对象!(当然调用inner对象也需要实例化)
    • 成员内部类可以调用外部类的所有成员。但是必须在创建了外部类的对象后,才能引用外部的成员。
  2. 静态内部类
    • 作为类的静态(static成员,存在于某个类的内部(Static修饰(特例))
    • 由于静态成员可以在不创建类的情况下被使用,因此,我们可以不创建outer类的对象,而直接引用inner类。
    • 静态内部类可以引用外部类的静态成员变量和静态方法!但是不能使用外部类的普通成员(因为Static修饰的东西是在类加载的时候就已经加载进入了jvm
    • Outer.Inner.属性、方法
  3. 局部内部类
    • 局部内部类是在外部类的方法内定义的类,相当于我们方法内定义的一个临时变量,在方法执行完毕后就从内存中清除。
      • 特点1:不能加访问修饰符,不能加可选修饰符
      • 特点2:只能在定义这个内部类方法的内部使用
      • 特点3:在方法内调用这个局部内部类也需要将这个局部内部类先实例化。
  4. 匿名内部类
    • 存在于某个类的内部,是一个无类名的类,它的定义和创建合并在一起,整个动作看起来像产生对象似的。
    • 匿名内部类是唯一对象而定义的类,但我们只需要创建一个类的对象,而且用不上它的名字的时候,使用内部类可以使代码看上去更清楚。
    • 形式
      new 类或者接口的名字(){ // 匿名内部类的主体}
内部类访问权限
调用外部类 定义自身属性 调用外部类静态属性 外部类内部被调用 第三方类调用
普通内部类 可以全部调用 非静态、特殊、Static、Final 外部类.this.属性 new对象后无视访问修饰符 根据修饰符
静态内部类 只能访问Static的属性 可以是静态和非静态 外部类名.属性 可以new,也可不用,同样无视访问修饰符 根据修饰符
package com.lovo.innerclass;

import com.lovo.innerclass.OutClass1.InnerClass1;

public class OutClass1 {
	//成员内部类
	//位置:位于外部类的全局位置
	//访问修饰符:决定能否在第三方类中使用该内部类
	//class文件名:外部类名字$内部类名字。
	//产生对象:可以在外部类的任意方法中,也可以在第三方类的方法中(考虑访问修饰符)
	public class InnerClass1{
		
		//属性:不能定义static的属性
		private int innerField1;
		
		int a;
		
		//方法:不能定义static的方法
		public void innerMethod(){
			//可以访问外部类的任意属性和方法
			//使用this代表的是内部类对象
			//如果内部类属性与外部类属性同名:使用外部类类名.this.属性名调用外部类的属性
			//如果内部类方法与外部类方法同名:使用外部类类名.this.方法名调用外部类的方法
		}
	}
	
	public void outMethod(){
		//可以直接产生内部类对象,然后无视访问修饰符视情况调用其属性和方法
		InnerClass1 ic1 = new InnerClass1();
		ic1.innerField1 = 199;
	}
}

class ThirdClass1{
	
	public static void main(String[] args) {
		//在第三方类中产生内部类对象,必须先产生外部类对象
		OutClass1 oc1 = new OutClass1();
		//使用特殊外部类对象.new的语法产生内部类对象
		OutClass1.InnerClass1 inc1 = oc1.new InnerClass1();
		//根据访问修饰符视情况调用属性和方法
		inc1.innerMethod();
	}
}
package com.lovo.innerclass;

public class OutClass2 {
	static int a;
	// 静态内部类
	// 位置:位于外部类的全局位置,但是添加static修饰符
	// 访问修饰符:决定能否在第三方类中使用该内部类
	// class文件名:外部类名字$内部类名字
	//产生对象:可以在外部类的任意方法中,也可以在第三方类的方法中(考虑访问修饰符)
	public static class InnerClass2 {
		//属性可以定义静态和非静态的
		private int innerFiled21;
		private static int innerFiled22;
		private int a;
		
		//方法可以定义静态和非静态的
		public void innerMethod21() {
			//只能访问外部类的静态属性和静态方法
			//this代表内部类对象
			//如果属性方法出现同名的情况,用外部类类名.的方式特制外部类中的属性方法
		}
		public static void innerMethod22() {
			//只能访问外部类的静态属性和静态方法
		}
	}
	
	public void a(){
		//直接new出内部类对象
		InnerClass2 ic2 = new InnerClass2();
		//用对象名.的方式访问内部类的非static属性和方法,无视访问修饰符
		ic2.innerFiled21 = 100;
		//用内部类类名.的方式访问内部类的static属性和方法,无视访问修饰符
		InnerClass2.innerMethod22();
	}
}

class ThirdClass2{
	
	public static void main(String[] args) {
		//无需产生外部类对象,使用外部类类名.内部类类名的方式产生内部类对象
		OutClass2.InnerClass2 ic2 = new OutClass2.InnerClass2();
		//根据访问修饰符,调用属性和方法
		ic2.innerMethod21();
	}
}
package com.lovo.innerclass;

public class OutClass3 {
	
	public void outMethod(){
		//局部内部类
		//位置:在外部类的某个方法内部
		//访问修饰符:没有
		//class文件名字:外部类类名&数字编号+内部类类名
		//产生对象:只能在内部类所在的方法中
		class InnerClass3{
			//只能定义非static的属性和方法
			private int innerField31;
			public void innerMethod31(){
				//如果outMethod是静态的,则不能访问外部类的非静态属性和方法;其他情况都可以访问
				//this代表当前内部类对象
				//如果内部类属性与外部类属性同名:使用外部类类名.this.属性名调用外部类的属性
				//如果内部类方法与外部类方法同名:使用外部类类名.this.方法名调用外部类的方法
				//无法访问内部类所在方法的变量,只能访问常量
			}
		}
		
		//直接new出来即可
		InnerClass3 ic3 = new InnerClass3();
		//无视访问修饰符视情况调用其属性和方法
		ic3.innerField31 = 100;
	}
}
package com.lovo.innerclass;

public class OutClass4 {
	
	public static void outMethod(){	
		//匿名内部类
		//位置:在外部类的某个方法内部,new对象的同时定义属性行为,所以只能用这一次
		//访问修饰符:不存在
		//class文件名:外部类的类名&数字编号
		new Object(){
			//只能定义非static的属性和方法
			private int innerField41;
			
			public void innerMethod41(){
				//如果outMethod是静态的,则不能访问外部类的非静态属性和方法;其他情况都可以访问
				//this代表当前的匿名内部类对象
				//如果内部类属性与外部类属性同名:使用外部类类名.this.属性名调用外部类的属性
				//如果内部类方法与外部类方法同名:使用外部类类名.this.方法名调用外部类的方法
				//无法访问内部类所在方法--即outMethod()中的的局部变量,只能访问常量
			}
		};
		
	}
}

 

Jalena

原创内容,转载请注明出处! 部分内容来自网络,请遵守法律适用!

文章评论