day10
1. 内部类(了解)
1.1 内部类的介绍
- 将一个类定义在另外一个类的内部, 这个类称为内部类; 内部类可以定义在成员位置, 也可以定义在方法中, 根据内部类定义的位置不同, 因此分为成员内部类和局部内部类
- 为什么定义内部类:
定义出一个Body身体类
class Body{// 外部类
class Heart{// 内部类
// 心脏 属性 : 颜色, 心跳, 血压 功能 : 跳动,供血, 于是认为将心脏定义成一个类, 表示心脏属性和功能
}
}
- 根据内部类定义位置不同:
a : 成员内部类(成员内部类, 理解成一个成员变量在使用)
普通成员内部类
私有成员内部类
静态成员内部类
b: 局部内部类(定义在方法中的内部类)
普通局部内部类
匿名内部类(掌握)
1.2 普通成员内部类
- 定义位置: 内部类定义在外部类的成员位置
- 格式:
class Body{// 外部类
class Heart{// 普通成员内部类
// 属性, 方法功能
}
}
- 普通成员内部类的使用:
1) 普通成员内部类可以直接使用外部类中的成员
2) 在外部类中想要使用内部类中的成员内容, 需要创建出一个内部类对象, 内部类对象.调用内部类中的属性,功能
3) 普通成员内部类, 想要在其他类型中直接使用内部类, 有公式创建出内部类对象:
外部类.内部类 内部类名 = new 外部类对象().new 内部类对象();
代码
package com.ujiuye.inner; public class Body {// 外部类 // blood 表示血压概念 int blood = 120; class Heart{// Heart类理解成一个普通的成员变量 int jump = 100; public void show() { // 1)普通成员内部类可以直接使用外部类中的成员 System.out.println("血压" + blood + ",每分钟心跳为" + jump); } } // 定义出方法功能 : 使用内部类Heart public void useHeart() { System.out.println(blood); // 创建出一个内部类对象 Heart h = new Heart(); System.out.println(h.jump); h.show(); } } |
package com.ujiuye.inner; public class TestInnerClass { public static void main(String[] args) { // 1. 测试普通成员内部类 Body b = new Body(); b.useHeart(); System.out.println(b.blood); System.out.println("--------------------"); // 在其他的类中, 获取出普通成员内部类对象 // 外部类.内部类 内部类名 = new 外部类对象().new 内部类对象(); Body.Heart heart = new Body().new Heart(); System.out.println(heart.jump); heart.show(); } } |
1.3 私有成员内部类
- 定义位置: 内部类定义在外部类的成员位置,但是需要使用private关键字修饰内部类
- 格式 :
class Body1{// 外部类
private class Gan{// 私有成员内部类
// 属性, 方法功能
}
}
- 私有成员内部类使用:
1) 私有成员内部类可以直接使用外部类中的成员
2) 私有成员内部类只能在外部类中创建出对外公共访问方式, 因为私有成员在其他类型中无法直接访问
代码
package com.ujiuye.inner; public class Body1 {// 外部类 // 私有成员在本类中使用一切正常, 不能在其他类型中直接使用 private int day = 1; public int getDay() { return day; } public void setDay(int day) { this.day = day; } // 定义出一个私有成员内部类 private class Gan{// 将Gan理解成一个私有成员变量 String color = "灰色"; int drink = 10; public void show() { System.out.println(day + "天,喝" + drink + "斤白酒,你的肝颜色变成:" + color); } } // 定义出一个功能 : 提供私有成员内部类Gan对外公共访问方式 public void useGan() { // 1. 创建出一个私有成员内部类对象 Gan gan = new Gan(); System.out.println(gan.color + "---" + gan.drink); gan.show(); } } |
package com.ujiuye.inner; public class TestInnerClass { public static void main(String[] args) { // 2. 测试私有成员内部类 Body1 b1 = new Body1(); b1.useGan(); } } |
1.4 静态成员内部类
- 定义位置: 内部类定义在外部类的成员位置,但是需要使用static关键字修饰内部类
- 格式:
class Body2{ // 外部类
static class Shen{// 静态成员内部类
// 属性, 方法
}
}
- 静态成员内部类使用:
1) 静态成员内部类中,可以直接使用外部类中的静态成员, 但是外部类中的非静态成员, 需要先创建出外部类对象, 使用外部类对象.调用
2) 静态成员内部类中的非静态变量和方法功能, 需要创建出静态成员内部类对象, 使用对象名.调用
语法结构:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
代码
package com.ujiuye.inner; public class Body2 { // 静态属于类, 不属于任何对象, 但是可以被对象共享使用 // 静态中不能直接使用非静态(包括成员变量, 非静态方法), 非静态要使用, // 需要创建出对象, 使用对象名.调用 static int day = 1; int drink = 5; // 定义出一个静态成员内部类 static class Shen{ // 静态成员内部类理解成一个静态成员变量 static int wc = 6; int i = 10; public void show() { // 创建出一个外部类类型Body2 Body2 b2 = new Body2(); // 1)静态成员内部类中,可以直接使用外部类中的静态成员, 但是外部类中的非静态成员, // 需要先创建出外部类对象, 使用外部类对象.调用 System.out.println(day + "天" + "喝了" + b2.drink + "升水,去排毒" + wc + "次, 少了, 如果去了"+ i +"次会更好"); } } } |
package com.ujiuye.inner; public class TestInnerClass { public static void main(String[] args) { // 3. 测试静态成员内部类 System.out.println(Body2.Shen.wc);// 6 // 外部类名.内部类名 对象名 = new 外部类名.内部类名(); Body2.Shen shen = new Body2.Shen(); System.out.println(shen.i); shen.show(); } } |
1.5普通局部内部类
- 定义位置: 局部内部类定义在方法当中
- 格式:
public void breath(){// 方法
class Fei{// 局部内部类
// 属性,方法功能
}
}
- 局部内部类使用:
1) 局部变量定义在方法中, 跟着方法运行存在于内存中, 跟着方法运行完毕,出内存, 无法单独获取到方法中的局部变量
2) 同理, 局部内部类, 无法单独获取到, 局部内部类只能在当前定义方法中进行使用, 于是在方法中,创建出局部内部类对象, 通过对象.调用布局内部类中的属性和功能,外界通过调用局部内部类所在的方法,相当于对局部内部类进行使用
代码
package com.ujiuye.inner; public class Demo01_局部内部类 { public static void main(String[] args) { breath(); } public static void breath() { int count = 10; // 局部变量 // 定义出局部内部类 class Fei{// 局部内部类理解成一个局部变量使用 String color = "黑色"; public void somke() { System.out.println("每天吸" + count + "根烟,慢慢的肺有可能会变成" + color); } } System.out.println(count);// 10 // 创建出局部内部类对象 Fei fei = new Fei(); System.out.println(fei.color);// 黑色 fei.somke();// 每天吸10根烟,慢慢的肺有可能会变成黑色 } } |
1.5 匿名内部类(掌握)
- 匿名对象: new Person();
匿名对象只能使用一次
new Person().属性或者方法;
- 匿名内部类本质:
匿名内部类可以作为一个类的子类或者作为一个接口的实现类
- 匿名内部类语法结构:
语法整体是一个匿名内部类的对象创建
new 父类或者父接口(){
// 重写父类和父接口中需要重写方法功能
};
a : 匿名内部类对象, 只能使用一次
b : 优化匿名内部类对象使用
在创建好匿名内部类对象之后, 使用多态的方式, 以匿名内部类实现的父类或者父接口作为等号左边的变量引用, 等号右边是匿名内部类对象, 多态表达式成立, 可以多次使用匿名内部类中重写和继承到的方法和属性功能
代码
package com.ujiuye.inner; public class Demo02_匿名内部类 { // 匿名内部类可以简化类与接口实现关系 public static void main(String[] args) { // 整段匿名内部类代码表示创建出一个MyInter实现类对象,只能使用一次 new MyInter() {// 一对大括号就表示接口MyInter实现类,大括号中是实现过程 @Override public void fun() { System.out.println("我是匿名内部类实现的fun"+I); } }.fun(); // 匿名内部类实现接口MyInter2 // 父接口 名 = 实现类对象; 多态 MyInter2 my = new MyInter2() { // 大括号表示MyInter2接口的实现类, 实现过程 @Override public int getSum(int x, int y) { return x + y; } @Override public void print(String s) { System.out.println(s); } }; my.print("123");// 123 System.out.println(my.getSum(5, 6));// 11 } } interface MyInter{ int I = 10; public abstract void fun(); } interface MyInter2{ public abstract int getSum(int x, int y); public abstract void print(String s); } |
2. 4种权限修饰符
- 4种权限修饰 : 表示作用范围
public : 公共的, 最大使用权限, 当前项目工程下都可以使用
protected : 受保护权限, 关键字, 能体现出封装
默认权限 : 定义类, 接口, 方法, 成员变量, 没有给出任何权限修饰, 那么默认权限, 默认权限不能写出来, 写出来报错
private : 私有, 最小使用权限, 当前类中使用
- 4种权限使用范围
本类中使用 |
本包中使用 |
外包子类中使用 |
外包中无关类 |
|
private |
可以 |
|||
默认权限 |
可以 |
可以 |
||
protecte受保护权限 |
可以 |
可以 |
可以 |
|
public 公共权限 |
可以 |
可以 |
可以 |
可以 |
- 注意 :
protected : 受保护权限,可以在外包子类内部使用, 出了子类之外,无法使用
受保护的权限被外包子类继承到, 在子类中相当于private私有使用
代码
package com.ujiuye.quanxian; // 默认修饰的类 class Demo01_默认修饰类 { // 默认修饰的成员 int i = 10; public void useI() { System.out.println(i); } } |
package com.ujiuye.quanxian; public class Demo02_受保护权限 { protected int pro = 20; // fun是一个受保护权限修饰 protected void fun() { System.out.println(pro); } } |
package com.ujiuye.quanxian; public class Demo03_公共权限 { int i = 10; public void function() { System.out.println("--------------" + i); } } |
package com.ujiuye.quanxian; public class Test权限 { public static void main(String[] args) { // 1. 测试默认权限修饰的类,可以在同一个package包下使用 Demo01_默认修饰类 demo = new Demo01_默认修饰类(); System.out.println(demo.i);// 10 demo.useI();// 10 // 2. 测试受保护权限在同一个package包下使用 Demo02_受保护权限 demo2 = new Demo02_受保护权限(); System.out.println(demo2.pro); demo2.fun(); // 3. 测试公共权限在本包中可以使用 Demo03_公共权限 demo3 = new Demo03_公共权限(); demo3.function(); } } |
package com.ujiuye.otherquanxian; import com.ujiuye.quanxian.Demo02_受保护权限; public class Demo02受保护权限Sub extends Demo02_受保护权限 { // 继承到了父类中的 受保护成员变量pro, 受保护方法功能 fun // 受保护权限只能在外包子类中的使用 public void useProtected() { System.out.println(pro); fun(); } } |
package com.ujiuye.otherquanxian; import com.ujiuye.quanxian.Demo02_受保护权限; import com.ujiuye.quanxian.Demo03_公共权限; public class Test外包权限 { public static void main(String[] args) { // Demo01_默认修饰类 demo = new Demo01_默认修饰类(); 默认权限无法在外包中使用 // 测试受保护权限在外包子类中保护程度 Demo02受保护权限Sub demo2Sub = new Demo02受保护权限Sub(); demo2Sub.useProtected(); // System.out.println(demo2Sub.Pro); 受保护的权限被外包子类继承到, 在子类中相当于private私有使用 Demo02_受保护权限 demo2 = new Demo02_受保护权限(); // demo2.pro; 受保护的权限在外包无关类中不能使用 // 测试公共权限在外包子类的使用 Demo03公共权限Sub demo3 = new Demo03公共权限Sub(); demo3.function(); // 测试公共权限在外包无关类中使用 Demo03_公共权限 pub = new Demo03_公共权限(); pub.function(); } } |
3. API和类库
3.1 API的使用
- API : 全称应用程序接口, API是JDK给开发人员提供的参考文档(帮助文档), 因为JDK给开发人员提供很多的核心类库功能, 所以对应有帮助文档, 为了解释说明 : 类型的功能, 构造方法, 成员变量, 方法功能等使用规则
- 每一个JDK版本都对应有API帮助参考文档
- 如何使用API:
1) 双击打开对应的API帮助文档
3.2 类库
- java源文件.java文件, 编译后的文件.class字节码文件, 最终在内存中运行的就是.class文件, 因为.class文件中包含了类型中的所有内容
- 实际开发中项目工程中很多的包, 每个包下有很多的独立类型文件, 最终需要将实现的代码功能交付给客户, 就是交付.class文件, 需要将大量的.class文件进行打包, 生成一个jar包, jar包是java中的代码标准压缩包, 只要在项目中导入jar包, 那么这个jar包中的所有的类型都可以使用和运行
- JDK的核心类库
- 将代码打包成jar包文件:
1) 选中需要打成jar包的项目工程或者是package包
2) 点击选中的工程或者包
鼠标右键--->export-->java--->jar file--->选择jar文件存放的路径和定义jar文件的名称-->finish完成即可
- 如何将jar包导入到项目工程中使用:
1) 复制需要使用的jar包, 到项目工程根目录下
2) 将jar包下的所有的文件路径导入到项目工程中, 目标jar包变成奶瓶标志, 然后目标jar包中的类型就可以使用
效果:
- 删除不需要的jar包:
4. Object类型
4.1 Object类型的概述
- Object类 : 所有类的父类 , 来自于java.lang包, 使用不需要导包
- Object类是所有类的父类:
如果类没有手动继承父类,那么Object类就是这个类的直接父类
class A{} // Object类就是A的父类
class B extends A{}
- Object类中有一个空参数构造:
空参数构造中第一行不再调用super(), 因为Object类没有父类,创建对象, 正常;
4.2 toString方法
- toString() : 将调用toString方法的对象以字符串形式进行表示, 将字符串进行返回
- toString方法源代码:
public String toString() {
com.ujiuye.object.Person @ 15db9742
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
1) getClass().getName() : 表示获取当前类型的全名
2) "@" : 字符串@
3) hashCode() : 表示计算出一个对象的哈希值, 就是将一个对象在内存中的物理地址, 转换成程序员可以理解数据形式, int类型整数
4) Integer.toHexString(int i) : 表示将参数的int类型整数转换成16进制数进行表示
结果 : com.ujiuye.object.Person@15db9742 称为对象的地址
- 实际开发中, 输出打印对象的内存地址没有意义, 因此,需要Object的子类重写父类中的toString方法功能, 不需要自己重写, 使用快捷键 alt + shift + s , 选择toString, 重写之后会将当前对象中的成员变量内容进行输出
- println就是一个输出打印的方法 : 如果输出的是引用数据类型, 那么方法功能自动调用对象中的toString方法
代码
package com.ujiuye.object;
// 因为Person没有直接父类, 那么object就是Person的父类 public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } |
package com.ujiuye.object; public class Test { public static void main(String[] args) { Person p = new Person();
String s = p.toString(); System.out.println(s); // Person [name=null, age=0] // println就是一个输出打印的方法 : 如果输出的是引用数据类型, 那么方法功能自动调用对象中的toString // 方法作为输出结果 System.out.println(p); // Person [name=null, age=0] } } |