内部类和常用类
一,内部类
1.什么是内部类
概念:在一个类的内部再定义一个完整的类。
特点: 编译之后可别分生成独立的字节码文件。 内部类可直接访问外部类的私有成员,而不破坏封装。 可为外部类提供必要的内部功能组件。
2.分类
3.成员内部类
成员内部类类比于实例变量。 位置:类以内,方法以外。 创建成员内部类的对象,需要依赖于外部类的对象进行创建 成员内部类可以直接访问外部类的私有成员 外部类类名.this :指向外部类的当前对象 外部类类名.this.属性:访问外部类的属性
package com.sk.test;
public class Dome01 {
private String name;
public void a(){
System.out.println("外部类的方法");
/*外部类可以通过new对象访问内部类*/
A a=new A();
a.name="张三";
//a.b();
}
/**成员内部类:类中,方法外*/
class A{
private String name;
int age;
public void b(){
System.out.println("内部类方法");
//内部类可以直接访问外部类成员
a();
name="ss";//赋值内部类
//外部类类名.this.属性="";
Dome01.this.name="lisi";
}
//class B{}//内部类也可以有自己的内部类
// public A(String name, int age) {
// this.name = name;//可以有自己的构造方法
// this.age = age;
// }
}
}
package com.sk.test;
public class DomeTest01 {
public static void main(String[] args) {
//没有拌饭直接创建对象
//Dome01.A a=new Dome01.A();
//1.需要先创建外部类对象才能创建内部类对象
Dome01 d=new Dome01();
Dome01.A a=d.new A();
a.b();
}
}
4.静态内部类
静态内部类类比静态变量 位置:定义在类以内,方法以外,被static修饰
创建静态内部类的对象,需要依赖于外部类的类名: Outer.Inner i = new Outer.Inner()
静态内部类中静态成员可以直接通过类名访问: Outer.Inner.静态属性名 Outer.Inner.静态方法名(实际参数); 静态内部类只能直接访问外部类的静态成员(静态属性和静态方法)
package com.sk.test;
public class Dome02 {
String name;
static int age;
public void aa(){
B.b=123;
B.b();
}
public static void b(){}
static class B{
String a;
static int b;
public static void b(){}
public void a(){
//静态内部类只能访问外部类的静态成员
//Non-static field 'name' cannot be referenced from a static context
//System.out.println(name);//
System.out.println(age);
//aa();
b();
}
}
}
package com.sk.test;
public class DomeTest02 {
public static void main(String[] args) {
//1.使用对象
Dome02.B b=new Dome02.B();
b.a();
b.a="9";
//使用类进行访问
Dome02.B.b=12;
Dome02.B.b();
}
}
5.局部内部类
局部内部类类比于局部变量 位置:定义在方法以内
创建局部内部类的对象:必须在定义它的方法内部创建。
局部内部类可以直接访问外部类的私有属性
局部内部类只能够可以访问外定义它的方法内部的局部变量,但是要求此局部变量必须被final修饰。 注意:JDK8.0及以上版本会对 被局部内部类访问的局部变量默认添加final。
package com.sk.test;
public class Dome03 {
static int d;
int c;
public void a(){
int b=0;
/*局部内部类,一般只有本方法有用,其他方法用不到*/
class C{
String a;
public void a(){
System.out.println(c);
System.out.println(a);
/*局部内部类只能够可以访问外定义它的方法内部的局部变量,但是要求此局部变量必须被final修饰。
注意:JDK8.0及以上版本会对 被局部内部类访问的局部变量默认添加final。*/
System.out.println(b);
}
}
//b=10;
C cc=new C();
cc.a();
}
public static void main(String[] args) {
Dome03 d=new Dome03();
d.a();
}
}
6.匿名内部类
匿名内部类:是一种特殊的局部内部类,局部内部类具有的特点它也具备。 特殊性: 匿名内部类必须实现一个接口或是继承一个类 基于一个匿名内部类只能创建该类的一个对象,而且对象的创建和类的定义一起完成
语法: 类名/接口名 引用 = new 类名/接口名(){};
package com.sk.test;
public class Dome04 {
public static void main(String[] args) {
int a=9;
int b=10;
//计算a+b
//1.传统方式需要先写一个实现类,然后调用实现类的方法
A2 a2=new A2();
System.out.println(a2.math(a,b));
//2.使用匿名内部类,不需要新建类去实现接口
A1 a1=new A1() {
@Override
public double math(double a, double b) {
return a+b;
}
};//相比于传统方式,不需要专门创建类
System.out.println(a1.math(a,b));
}
}
interface A1{
public double math(double a,double b);
//如果按照传统的实现方式
//实现+-/*%需要写5各类
//如果有的类只用一次,可以使用匿名内部类
}
class A2 implements A1{
@Override
public double math(double a, double b) {
return a+b;
}
}
7.Lambda表达式
Lambda表达式:实现函数式接口,并创建对象(匿名内部类的简化写法)。 Lambda表达式的语法: 接口名 引用 = (形参列表) -> { //方法实现 }; -> 左侧:指定Lambda表达式所需要的参数,即接口中方法的参数。 -> 右侧:指定Lambda表达式的执行功能部分,即实现接口中方法对应方法的实现部分。 利用Lambda表达式实现的接口,接口中必须只定义一个抽象方法,即必须是函数式接口。
package com.sk.test;
public class Dome05 {
public static void main(String[] args) {
double a1=9,b1=10;
//接口名 引用 = (形参列表) -> { //方法实现 };
//完整写法
C c=(double a,double b)->{double cc=a+b;return cc;};
//省略参数类型
C c1=(a,b)->{double cc=a+b;return cc;};
//省略大括号: 当方法体,只有一行内容,可以省略{}
//省略return语句:当方法体只有一个符合返回值类型的结果时
C c2=(a,b)-> a+b;
System.out.println(c2.math(a1,b1));
}
}
/**函数式接口:接口中只有一个方法*/
interface C{
public double math(double a,double b);
}
练习
根据年龄给学生类进行排序
package com.sk.test;
public class Student {
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;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
package com.sk.test;
import java.util.Arrays;
import java.util.Comparator;
public class StudentTest {
public static void main(String[] args) {
Student s1=new Student("zs",19);
Student s2=new Student("zs",12);
Student s3=new Student("zs",198);
Student s4=new Student("zs",122);
Student s5=new Student("zs",1452);
Student s6=new Student("zs",1287);
Student s7=new Student("zs",1782);
Student s8=new Student("zs",87812);
Student s9=new Student("zs",4512);
Student s10=new Student("zs",8612);
Student[] st={s1,s2,s3,s4,s5,s6,s7,s8,s9,s10};
System.out.println("***************未排序*********************");
for (int i=0;i<st.length;i++){
Student s=st[i];
System.out.println(s.getName()+"\t"+s.getAge());
}
//匿名内部类
// Comparator<Student> com=new Comparator<Student>() {
// @Override
// public int compare(Student o1, Student o2) {
// return o1.getAge()-o2.getAge();
// }
// };
Comparator<Student> com=(a,b)->a.getAge()-b.getAge();
Arrays.sort(st,com);
System.out.println("************排序****************");
for (int i=0;i<st.length;i++){
Student s=st[i];
System.out.println(s.getName()+"\t"+s.getAge());
}
}
}