1.内部类
package com.itheima05.innerclass;
/*
* 1. 定义在一个类A内部的另外一个类B, 那么A称之为外部类, B称之为内部类
* 内部类: 访问受限(要通过外部来访问内部)
* 2. 成员内部类: 定义一个类成员位置的类 (少见)
* 1. 语法:外部类名.内部类名(声明) 变量名 = 外部类对象.new 内部类();
* 2. 编译:多了一个:OuterClass$InnerClass.class
* 3. 局部内部类: 定义在一个方法里的类。只能当前方法内使用,其他方法不能使用
*/
public class InnerDemo {
//有.class文件
public static void main(String[] args) {
class MethodClass{
//定义在main方法里称为局部内部类
int methodField;
void method(){
}
}
MethodClass mc = new MethodClass(); //上面的类
mc.methodField = 1;
mc.method();
}
public static void method01(){
OuterClass oc = new OuterClass(); //main方法外面即下面的类
oc.outerField = 1;
oc.outerMethod();
OuterClass.InnerClass ic = oc.new InnerClass(); //main方法外面即下面的类
ic.innerFiled = 2;
ic.innerMethod();
// MethodClass mc = new MethodClass(); //错误,不能访问
}
}
class OuterClass{
//外部类 //有.class文件
int outerField; //成员
void outerMethod(){
}
class InnerClass{
//成员内部类 //有.class文件
int innerFiled;
void innerMethod(){
}
}
}
2.匿名内部类
package com.itheima05.innerclass;
/*
* 1. 匿名内部类 属于 方法/局部内部类 的一种
* 2. 匿名内部类 没有 类名
* 3. 目的 : 简化代码编写
* new 父类/父接口() { //class body 即类体
* 如果有抽象方法,必须重写
* }
* 创建出来的是父类/父接口的子类对象
* 原理: 定义类+创建对象 合二为一
*/
public class InnerDemo02 {
public static void main(String[] args) {
Dog twoHa = new Dog(); //Animal twoHa = new Dog();也可以即多态
voice(twoHa); //汪汪叫
//11111111111111111111111111111111111111111111111111111111111111111111111111111
//InnerDemo02$Wolf.class //第一个内部类有名字Wolf
class Wolf implements Animal{
//以前这类写在main方法外 //定义类
@Override
public void shout() {
System.out.println("嗷嗷叫");
}
}
Wolf greyTai = new Wolf(); //创建对象
voice(greyTai); //嗷嗷叫
//111111111111111111111111111111111111111111111111111111111111111111111111111111111
/*
* 类名如dog,wolf其实在某些场景下一定都不重要,重要的类体(重写shout方法)
* 语法: 多了个类体,但是把类名隐藏掉了叫匿名
* 省略: 1. 以前: 定义类 然后 创建对象
* 2. 现在: 创建对象+定义类 合二为一
*/
// Animal a = new Animal(); //接口不能实例化,如下加方法体
// 父接口 变量 = 父接口子类对象 (向上转型)
Animal a = new Animal(){
//多了一个大括号,InnerDemo02$1.class 第二个内部类也是第一个匿名内部类用1
@Override
public void shout() {
System.out.println("嘎嘎叫");
}
};
voice(a); //嘎嘎叫
//111111111111111111111111111111111111111111111111111111111111111111111111111111111
// InnerDemo02$2.class //第三个内部类也是第二个匿名内部类用2
Animal b = new Dog(){
//这样写也可以,同上
@Override
public void shout() {
System.out.println("呱呱叫");
}
};
b.shout(); // 呱呱叫
//1111111111111111111111111111111111111111111111111111111111111111111111111111111
//匿名内部类的匿名对象,最简洁 //InnerDemo02$3.class
voice(new Animal() {
@Override
public void shout() {
System.out.println("喵喵叫"); // 喵喵叫
}
});
}
//Animal接口, 接口不能实例化
private static void voice(Animal a) {
a.shout();
}
}
//111111111111111111111111111111111111111111111111111111111111111111111111111
interface Animal{
//一般不用abstract Animal
void shout(); //叫
}
class Dog implements Animal{
//多态,匿名内部类不用
@Override
public void shout() {
System.out.println("汪汪叫");
}
}
如下这个类对象就用一次,没必要取个名字,如果取名字还要单独的.java文件
3.练习
子类特有方法
不是子类重写方法
,如下2解决
package com.atguigu.test10;
/*
(1)声明一个抽象类Father,包含抽象方法:public abstract void method();
(2)用匿名内部类继承Father,并重写抽象方法,打印“hello 孩子"。并调用子类对象的method方法
*/
public class TestExer3 {
public static void main(String[] args) {
/*new Father(){
public void method(){
System.out.println("hello 孩子");
}
}.method();*/
// 上下一样
Father f = new Father(){
public void method(){
System.out.println("hello 孩子");
}
};
f.method(); //hello 孩子
}
}
abstract class Father{
public abstract void method();
}
接口、抽象类可以理解成是模糊不定的东西
,要使用它的特质必须要实例化。实例化不能直接通过new,如下代码不同于普通的实例化对象,而是通过new一个实现接口的匿名内部类Runnable,使用{}具体实现接口。
package com.atguigu.test10;
import java.util.Arrays;
import java.util.Comparator;
public class TestExer4 {
@SuppressWarnings("all")
public static void main(String[] args) {
//(2)在测试类中创建Employee数组
Employee[] all = new Employee[3];
all[0] = new Employee(2, "张三", 10000);
all[1] = new Employee(1, "李四", 30000);
all[2] = new Employee(3, "王五", 20000);
//(3)分别调用Arrays.sort(数组,Comparator),用匿名内部类实现按照编号升序排列,接口一定要重写方法
Arrays.sort(all, new Comparator(){
@Override
public int compare(Object o1, Object o2) {
Employee e1 = (Employee) o1;
Employee e2 = (Employee) o2;
return e1.getId() - e2.getId();
}
});
for (int i = 0; i < all.length; i++) {
System.out.println(all[i]);
}
// (4)分别调用Arrays.sort(数组,Comparator),用匿名内部类实现按照薪资升序排列
Arrays.sort(all , new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Employee e1 = (Employee) o1;
Employee e2 = (Employee) o2;
if(e1.getSalary() > e2.getSalary()){
return 1;
}else if(e1.getSalary() < e2.getSalary()){
return -1;
}
return 0;
}
});
for (int i = 0; i < all.length; i++) {
System.out.println(all[i]);
}
}
}
//(1)声明一个员工类Employee,有属性:编号、姓名、薪资
class Employee{
private int id;
private String name;
private double salary;
public Employee(int id, String name, double salary) {
super();
this.id = id;
this.name = name;
this.salary = salary;
}
public Employee() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";
}
}
B站/知乎/微信公众号:码农编程录