内部类
7.1: 定义:在一个类中的另外一个类。
eg:
.java ---> 小区
public class A{} ---> A栋
class B{} ---> B栋
class C{} ---> C栋
内部类:
.java ---> 小区
public classAA{} ---> AA栋
class AA_home -> AA栋内部的home
class BB{} ---> BB栋
class BB_home-> BB栋内部的home
class CC{} ---> CC栋
class AA_home class BB_home 就是内部类。
7.2:内部类的分类
7.2.1:成员内部类.
7.2.2:静态内部类.
7.2.3:局部内部类.
7.2.4:匿名内部类.
7.3, 成员内部类:
声明:在类中成员变量/成员方法位置编写。public class AA_home{};
注:在内部类中可以有成员方法,成员属性。
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:在外部类的方法调用成员内部类的属性方法
前提: 创建内部类对象 AA_home aw = new AA_home();
7.3.2.1:外部类方法调用内部类属性: aw.属性
7.3.2.2:外部类方法调用内部类方法: aw.方法名();
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的是接口的实现类,这个实现类就是匿名内部类充当了。
package com.briup.ch9;
/**
* 外部类<Br>
* 1,测试 内部类 能写什么
* 2,在内部类的方法中怎么访问外部类的资源
* 3,在外部类中的方法中怎么访问内部类的资源
* 4,在main方法中怎么访问内部类的资源
* */
public class Test4 {
public void show() {
int num = 10;
/**
* 局部内部类
* */
class Inner_Two{
}
}
public int age = 10;
/**
* 成员内部类<Br>
* 不能使用静态资源<br>
* */
public class Inner_One{
public int innage = 10;
public void oneShow() {
System.out.println("oneShow");
//调用外部类的静态方法
Test4.myshow();
//调用外部类的普通成员变量/成员方法
int myage = Test4.this.age;
Test4.this.show();
}
}
/**
* 调用内部类测试方法
* */
public void test() {
//外部类调用内部类的方法和属性
Inner_One one = new Inner_One();
System.out.println(one.innage);
one.oneShow();
}
/**
* main方法调用内部类的资源
* */
public static void main(String[] args) {
//调用成员内部类的资源
Test4 t = new Test4();
Inner_One one = t.new Inner_One();
one.oneShow();
}
public static String name = "tom";
public static void myshow() {
System.out.println("myshow");
}
/**
* 静态内部类
* */
public static class Inner_Three{
}
//匿名内部类
}
package com.briup.ch9;
/**
* 匿名内部类<br>
* <li>继承父类
* <li>实现父接口
* */
public class Test5 {
public static void main(String[] args) {
//使用匿名内部类继承父类F
F f = new F() {
public void show() {
System.out.println();
}
};
f.show();
//实现接口,实现接口中没有完成的方法
I1 i = new I1() {
@Override
public void show() {
System.out.println("匿名内部类实现接口");
}
} ;
i.show();
}
}
class F{
public void show() {
System.out.println("F");
}
}
class Z extends F{
public void show() {
System.out.println("z");
}
}
interface I1{
public void show();
}
class Impl implements I1{
@Override
public void show() {
System.out.println("show");
}
}
== 和 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使用 :
使用缓冲区解决每次拼接都产生新字符串的问题。
package com.briup.ch9;
import java.util.Arrays;
public class Test6 {
public static void main(String[] args) {
//创建字符串 1
// a b c d e
byte[] but = {97,98,99,100,101};
String s1 = new String(but,0,3);
System.out.println(s1);
//创建字符串 2
String s2 = new String("abc");
String s4 = new String("abc");
String s3 = "abc";
System.out.println(s2==s3);//地址 false
System.out.println(s2.equals(s3)); //比较值 true
System.out.println(s2==s4);//地址 false
//字符串中常用的方法 :
// API
//String 内部是 一个char[] value;
String s5 = "hello world";
char charAt = s5.charAt(0);
System.out.println(charAt);
String s11 = "taom";//97
String s12 = "teom";//101
int compareTo = s11.compareTo(s12);
System.out.println(compareTo);
//负数: s11 < s12
String s21 = "tom";
String s22 = new String("tom");
boolean equals = "".equals(null);
System.out.println(equals);
//运行
//ArrayIndexOutOf
//ClassCase
//NullPointer
String s31 = "hello world";
int indexOf = s31.indexOf("low");
System.out.println(indexOf);
String s41 = "hello world";
int lastIndexOf = s41.lastIndexOf("lo");
System.out.println(lastIndexOf);
// //java正则表达式
String s51 = "tam";
System.out.println(s51.matches("tom"));
//量词 控制数量
System.out.println(s51.matches("t.{2,4}m"));
//数量 至少3个
System.out.println(s51.matches("t.{3,}m"));
//数量任意 *
System.out.println(s51.matches("t.*m"));
//数量 0 - 1 ?
System.out.println(s51.matches("t.?m"));
//数量 1-n +
System.out.println(s51.matches("t.+m"));
// [] 方括号表达式 ,代表一个字符串,这个字符只能是[]中出现过的
s51 = "t_m";
System.out.println(s51.matches("t[A-z0-9]m"));
//伪代码,表示中文的范围
System.out.println(s51.matches("t[\u4e00-\u8888]m"));
//数字字母下划线
System.out.println(s51.matches("t\\wm"));
//正则约束 邮箱
//xiongzg@briup.com
//替换
String s61 = "你好to好m";
String replace = s61.replace("好", "");
System.out.println(replace);
String s71 = "tom lisi wangwu zhao";
String[] split = s71.split(" ");
System.out.println(Arrays.toString(split));
//拼接字符串...StringBuffer
String s81 = "hello";
//使用hello 字符串 创建 StringBuffer
StringBuffer sb = new StringBuffer(s81);
//拼接
sb.append("tom");
sb.append("lisi");
sb.append("赵六");
//StringBuffer缓冲区-->转换为字符串
String string = sb.toString();
System.out.println(string);
char[] v1 = new char[10];//存放出现过的字符
int index = 0;
int[] v2 = new int[10];//存放出现过字符的次数
for(int i = 0;i<s5.length();i++) {
char charAt2 = s5.charAt(i);
v1[index] = charAt2;
v2[index] = 0;
}
s511 = "t_m";
System.out.println(s511.matches("tm"));
System.out.println(s511.matches("t[A-z0-9]m"));//ASCALL码表中:A-z之间包含_ [ ] ^ `
System.out.println(s511.matches("t[\u4e00-\u8888]m"));
System.out.println(s511.matches("t.{1,}m"));//中文算一个,因为String底层是char数组
System.out.println(s511.matches("t.*m"));
System.out.println("人".getBytes().length);//UTF-8下,中文占3个字符
System.out.println("a".getBytes().length);
System.out.println(s511.matches("t\\wm"));//数字字母下划线 \w
String s611 = "你好to_好m";
String replace = s611.replace("好", " ");//替换所有的 好 为空格
System.out.println(replace);
System.out.println(s611.replaceAll("\\w","a" ));//不同点是:可以基于正则表达式的替换,
String s711 = " tom lis wangwu zhao";
String[] split = s711.split(" ");//每一个空格都会识别
System.out.println(Arrays.toString(split));
}
}
StringBuilder与StringBuffer:
注意:重写:返回值类型也可以不同,但返回值类型必须是父子类的关系