七:内部类
7.1: 定义:在一个类中的另外一个类。
7.2:内部类的分类
7.2.1:成员内部类.
7.2.2:静态内部类.
7.2.3:局部内部类.
7.2.4:匿名内部类.
7.3, 成员内部类:
声明:在类中成员变量/成员方法位置编写。
注:在内部类中可以有成员方法,成员属性。
7.3.1:在内部类的方法中使用
7.3.1.1:成员内部类中属性编写: 普通属性。静态属性需要被定义为final
7.3.1.2:成员内部类中方法编写: 普通方法
7.3.1.3:成员内部类中方法调用内部类属性:直接调用/this.属性名
7.3.1.4:成员内部类中方法调用内部类方法:直接调用/this.方法名()
7.3.1.5:成员内部类中方法调用外部类属性:外部类名.this.属性名
7.3.1.6:成员内部类中方法调用外部类方法:外部类名.this.方法名()
7.3.2:在外部类的方法调用成员内部类的属性方法
7.3.2.1:外部类方法调用内部类属性
7.3.2.2:外部类方法调用内部类方法
7.3.3:在main方法中使用内部类:
前提:先要获得外部类对象 MemberInner mi = new MemberInner();
7.3.3.1: 获得内部类对象: aw
1.3.1.1: AA_home aw = mi.new AA_home();
1.3.1.2: MemberInner.AA_home aw = mi.new AA_home();
7.3.3.2:调用内部类属性:aw.属性名;
7.3.3.3:调用内部类方法:aw.方法名();
7.4, 静态内部类: 即: 静态的成员内部类
声明:在类中静态成员变量/静态成员方法位置编写。public static class AA_home{};
静态内部类中可以声明静态成员和静态方法.
7.4.1:在内部类的方法中使用
7.4.1.1:静态内部类中属性编写: 可以定义静态属性和非静态属性
7.4.1.2:静态内部类中方法编写: 可以有静态方法和非静态方法
7.4.1.3:静态内部类中方法调用内部类普通属性:直接调用/this.属性名
7.4.1.3:静态内部类中方法调用内部类静态属性:直接调用/this.属性名。会有警告。静态的属性应该用静态的方式类调用
7.4.1.4:静态内部类中方法调用内部类普通方法:直接调用/this.方法名()
7.4.1.5:静态内部类中方法调用内部类静态方法:直接调用/this.方法名()
7.4.1.6:静态内部类中方法调用外部类普通属性: 不可以访问
7.4.1.7:静态内部类中方法调用外部类静态属性: 外部类名.属性
7.4.1.8:静态内部类中方法调用外部类普通方法: 不可以访问
7.4.1.9:静态内部类中方法调用外部类静态方法: 外部类名.方法名
总结:静态内部类,内部方法只能访问外部类的静态属性/方法。
7.4.2:在外部类的方法调用静态内部类的属性方法
普通属性方法:
前提: 创建内部类对象 AA_home aw = new AA_home();
7.4.2.1:外部类方法调用内部类属性: aw.属性
7.4.2.2:外部类方法调用内部类方法: aw.方法名();
静态属性方法:
7.4.2.1:外部类方法调用内部类属性: 静态内部类.属性
7.4.2.2:外部类方法调用内部类方法: 静态内部类.方法
7.4.3:在main方法中使用静态内部类:
原则:如果调用静态资源需要用类名直接调用,非静态的需要new对象。
AA_home aw = new AA_home()
aw.方法();
7.5, 局部内部类: 在局部代码块内部。
声明:在局部代码块中声明 class CC_home{};
局部内部类中只能有非静态方法,非静态属性(如果有静态属性需要被定义为final)
7.5.1:在局部内部类的方法中使用
7.5.1.1:局部内部类中属性编写: (静态+非静态)属性必须被定义final
7.5.1.2:局部内部类中方法编写: 普通方法
7.5.1.3:局部内部类中方法调用内部类属性:直接调用/this.属性名
7.5.1.4:局部内部类中方法调用内部类方法:直接调用/this.方法名()
7.5.1.5:局部内部类中方法调用外部类属性:外部类名.this.属性名
7.5.1.6:局部内部类中方法调用外部类方法:外部类名.this.方法名()
7.5.2:在外部类的方法调用局部内部类的属性方法
注意:这个是不可能被访问到的。
7.5.3:在main方法中使用内部类:
注意:这个是不可能被访问到的。
为什么外部类访问不到局部内部类的属性方法?
7.6, 匿名内部类: 没有构造器的类(不能手动写,系统会默认给)
一般用匿名内部类来实现某接口(使用不多,不需要写一个类实现该接口,可以使用匿名内部类)
匿名内部类一般就是用来实现接口:
所以: 重写接口(抽象类)中的方法。
可以在匿名内部类中写属性。
声明:
interface A{
public void show();
}
eg: A a = new A(){
public void showA(){
}
};
使用情景:面向接口编程,有时候写代码需要写一个类实现某个接口去完成某个功能,eg:集合中的比较器。
但这个功能只用一次,没有必要写一个类那么久可以使用匿名内部类来实现这个接口完成这个功能。
------------------------------
abstract class B{
public void showB(){}
public abstract void shohome();
}
eg:
B b = new B(){
//可以重写showB 可以不重写
public void shohome(){}//抽象方法一定要实现
};
解释:这里并不是new了接口, 而是多态, new的是接口的实现类,这个实现类就是匿名内部类充当了。
八:== 和 equals()区别
8.1: == 定义:比较内存地址是否相同。
8.2: equals()定义:Object类中的方法,Object中的equals()是比较内存地址是否相同。
注意:equals(Obj)是一个方法,所以只能是对象调用。equals是一个方法,所以可能被重写。
8.3: String类重写了equals()方法,所以在String对象调用equals时是比较值。
补充:
toString():当system输出对象的时候,其实是输出对象.toString();可以重写。
getClass():返回当前的真实对象,不可以重写。
String类的使用
字符串,【创建以后不能改变】,每一次拼接都会产生新的字符串。
构造方法:
new String(byte[],start,len);
new String("");
常用方法:
char = charAt(int index);
返回下标的字符
int = compareTo(String anotherString);
比较两个字符串
返回 字符串 相差
s11.compareTo(s12);
正数 s11 > s12
负数 s11 < s12
0 s11 == s12
boolean = equals(Object anObject)
比较两个字符串值是否相同
byte[] = getBytes(); 返回字符串的字节表现形式
* int = indexOf(""); 判断某个字符串在当前字符串中出现的位置 int : 第一次出现的下标 0 开始, 找不到 返回 -1
int = lastIndexOf(""); 从后往前找, int : 第一次出现的下标 0 开始,找不到 返回 -1
int = length(); 获取字符串的长度
* boolean = matches(String regex); "hello".matches("规则"); 使用hello字符串和规则进行匹配如果匹配成功(字符串符合定义的规则) 返回true
* String = replace(oldChar,newChar); 替换 :
String = replaceAll(String regex,String replacement);
* String[] = split(String regex); 分隔,打断
* String = subString(beginIndex);取子串 从beginIndex位置获取到最后
* String = subString(beginIndex,endIndex); 取子串 ,从beginIndex位置获取到endIndex
String = toLowerCase();返回小写
String = toUpperCase(); 返回大写
String = trim(); 去除字符串 左右 两端的空格
StringBuffer使用 : 使用缓冲区解决每次拼接都产生新字符串的问题。
九:基本数据类型与包装器类型
注意:包装器类型都重写了equals方法
9.1:对应包装器类型
boolean Boolean
byte Byte
short Short
char Character
int Integer
long Long
float Float
double Double
9.2:自动装箱和自动拆箱
在jdk1.5以后 基本数据类型和其包装器类型之间有自动装箱和拆箱过程。
注:是发生在编译阶段。
9.2.1:自动装箱: Integer i1 = 128; ----> Integer i1 = Integer.valueOf(128);
Integer i2 = 127; ----> Integer i2 = Integer.valueOf(127);
9.2.2:自动拆箱: int a1 = i1; ----> int a1 = i1.intValue();
int a2 = i2; ----> int a2 = i2.intValue();
9.2.3:valueOf():
源码:
IntegerCache.low = -128
IntegerCache.high = 127
cache 缓存
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
结论:自动装箱的时候,如果这个数字在[-128~127]之间那么就是从缓存中获取数据。
如果这个数字不在范围内,那么就是利用new关键字创建Integer对象()
问题一:Integer a = 128 , Integer b = 128;a == b ?--->false
Integer a = 127 , Integer b = 127;a == b ?--->true
9.2.4:intValue(): 以 int 类型返回该 Integer 的值。即返回的是栈中字面量同的地址。
结论:自动拆箱的时候,返回的是栈中字面量相同的地址。即: int n;
9.2.5:什么时候回发生自动装箱/拆箱问题。
当int 和 Integer互相转换的时候回发生。
eg: int a = new Integer("12");
eg: Integer b = 10;
* 9.3:Integer.parseInt("全数字字符串");把全数字的字符串转为int类型数据
eg:int a = Integer.parseInt("123");---> int : 123;
9.4:Integer.MAX_VALUE : 它表示 int 类型能够表示的最大值。
Integer.MIN_VALUE : 它表示 int 类型能够表示的最小值。
Integer.SIZE : 用来以二进制补码形式表示 int 值的比特位数。