内部类
1.什么是内部类?
答:定义在类中的类
2.怎么用的?
答:就像在类中定义属性一样
修饰符 class 类名{}
第一:内部类相当于是外部类中的一个属性
第二:内部类本身也就是一个类,跟正常的类一样
3.为什么要用它?
答:缩短类的生命周期
划分:内部类、局部内部类、匿名内部类
一:内部类
public class Outer { //创建外部类
public int count;
public void show() {
System.out.println("count=" + count);
}
public class Inner { //创建内部类
public void run() {
System.out.println("Inner run");
}
}
思路:1、把内部类当成是外部类中的一个成员,那么想要找到内部类就需要有外部类的对象
2、run方法需要对象进行调用的,而内部类的对象又需要外部类的对象进行调用
3、外部类.内部类 变量名 = 外部类对象.内部类对象
4、Outer.Inner inner = new Outer().new Inner();
public static void main(String[] args) {
//非静态内部类创建对象
//外部类.内部类 变量名 = 外部类对象.内部类对象
Outer.Inner inner = new Outer(). new Inner();
inner.run();
注意:1.当需要调用Inner类中的run方法时,要将内部类当成一个类来理解
2.当需要通过外部类来使用内部类时,首先需要将它看做一个外部类中的非静态属性来理解
/**
* 用于调用Inner类中的run方法
*/
public void method() {
Inner inner = new Inner();
inner.run();
}
method方法引用Inner类的run方法,就需要先创建对象,才能进行调用
此时可以用Outer对象调用method方法:
public static void main(String[] args) {
//非静态内部类创建对象
//外部类.内部类 变量名 = 外部类对象.内部类对象
Outer.Inner inner = new Outer(). new Inner();
inner.run();
Outer outer =new Outer();
outer.method();
内部类和不同的修饰同时存在时的特点:
1.对于该成员变量,其生命周期和对象的生命周期一致,作用域在整个类中都可以使用,调用形式:使用对象调用
2.private修饰后,该类就只能在当前类中使用
3.static修饰后,该类的生命周期和外部类的生命周期一致,就失去了内部类本身的意义
4.final修饰后,该类无法被继承
//在内部类中区分this关键词的所属
内部类可以调用外部类的属性和方法,但是外部类只能通过对象的形式去调用内部类中的属性和方法
public class Practive {
private int count =5 ;
class Inner{
int count =6;
public void show() {
int count=7;
System.out.println("count:"+ Practive.this.count);
}
}
public static void main(String[] args) {
Practive .Inner inner = new Practive().new Inner();
inner.show();
}
}
同一个类中方法及属性之所以可以互相调用,是因为都默认持有一个this对象
在继承中,子类中之所以可以直接调用父类中的方法是因为调用的父类方法或属性都默认持有一个super属性
二.局部内部类
1.局部变量只能在方法中使用
2.局部内部类本身也相当于一个局部变量,而其本身也是一个类
3.局部内部类就是定义在方法中的类,生命周期和方法的生命周期一致,作用域只在方法中
4.从方法的角度来使用,它要作为一个局部变量来使用,从自身的角度(需要使用类中的方法及属性)作为一个类来使用
public class AreaInnerDemo {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
class Outer{
public void method() {
class Inner{
public void show() {
System.out.println("--show--");
}
}
Inner inner = new Inner();
inner.show();
}
}
局部内部类中想要调用show方法, 需要先在method 方法中创建inner对象,然后在主函数中创建outer对象之后,再去调用method方法
三.匿名内部类
1.概念:定义在类中或方法中的内,该类没有具体的含义及名字
没有名字的内部类,没名字说明不经常用,内部类作用是为了缩短生命周期
2.匿名内部类实现语法:父类类名 名字 = new 父类类型(){};
new 父类类型(){}相当于就是一个子类对象
3.父类类名 名字 = new 父类类型(){};是多态形式,向上转型
public class NiMingInnerDemo {
public static void main(String[] args) {
Animal animal = new Animal() {
@Override
public void eat() {
System.out.println("没有名字的类");
}
@Override
public void sleep() {
System.out.println("第二个方法");
}
// public void show() { 接口中没有的方法是不能在匿名内部类中使用的
// System.out.println("展示");
// }
};
animal.eat();
animal.sleep();
}
}
interface Animal{
void eat();
void sleep();
}
class Cat implements Animal{
@Override
public void eat() {
}
@Override
public void sleep() {
}
}
自动拆装箱
1.自动拆装箱可以简单理解为基本数据类型的包装类
2.问题:为什么要对基础数据类型进行包装?
答:因为Java是一种面向对象语言,很多地方都需要使用对象而不是基本数据类型。比如,在集合类中,我们是无法将int 、double等类型放进去的。因为集合的容器要求元素是Object类型。
为了让基本类型也具有对象的特征,就出现了包装类型,它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
简单来说就是让它可以有更多的功能去使用。
3.基础数据类型对应的包装类:
byte – Byte; short–Short ; char–Character; int --Integer
long – Long ; float – Float ; double – Double ; boolean – Boolean
public static void main(String[] args) {
int num =5;
//Integer integer = new Integer(6);
Integer integer=6;
System.out.println(integer); // 6
System.out.println("-------------");
Integer integer1 = 127;
Integer integer2 = 127;
System.out.println(integer1 == integer2);//true 比较的是数值
System.out.println("-------------");
Integer integer3 = new Integer(127);
Integer integer4 = new Integer(127);
System.out.println(integer3 == integer4);// false 两个不同的地址
System.out.println(integer3.equals(integer4)); //true 先比较地址 再比较内容
System.out.println("-------------");
Integer integer5 =new Integer(128);
Integer integer6 =new Integer(128);
System.out.println(integer5 == integer6);//false 地址不同
System.out.println(integer5.equals(integer6));// true 数值相同,当数值大于127之后,可以使用new对象的方式
System.out.println("-------------");
Integer integer7= 128;
Integer integer8= 128;
System.out.println(integer7.equals(integer8));// true
//所有基本数据类型包装类中都提供了一个缓冲池
//缓冲池:将常用的数据存放到缓冲池中,以提高效率,存储的是固定的-128~127之间
//所有的赋值操作都是自动装箱,所有的运算都是自动拆箱
Integer integer9 =112;
Integer integer0 =113;
int result = integer9 -integer0;//从包装类拆成了数字运算
System.out.println(result); // 输出-1
System.out.println("-------------");
//所有的包装类中都提供了一个与字符串相互转换的方法
String count ="6";
int count2 = Integer.valueOf(count);
System.out.println(count2+1); //输出:7 如果没有转换成数字,结果应该是6+1
}
使用场景: 前段使用的输入框,用户输完内容后,获取的数字类型是字符串,为了方便,前段可能直接将数据传递到后台