面向对象
一、基本的面向对象
1.面向对象的设计思想
在现实世界生活:
类:抽象的概念,把具有相同特征和操作的事物归为一类
先有实体,再有类的概念
在我们代码的世界里:
类:抽象的概念,把具有相同属性和方法的对象归为一列
编写顺序:先有类,再创建对象
类的作用:类相当于一个模板,刻画出具有相同属性和方法的对象
2.面向对象和面向过程的区别
面向对象:
是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
面向过程:
就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
3.类与对象的关系
一个类可以有多个对象
类包含于对象,有类才能有对象。
比如:种群的划分,就是一个类,指定与其中一个,即为对象
//测试 public class Test{ //学生类 class Student(){ //属性 String name; char sex; int age; } public static void main(String[] args){ //创建对象 //学生类 对象1 新建 类名(); Student student=new Student(); //给属性赋值 student.name="榮十一"; student.sex='男'; student.age=22; //输出 System.out.println(student.name); System.out.println(student.sex); System.out.println(student.age); } }
3.1类的定义
给一切事物的名称的定义
3.2类中成员变量的定义
语法结构: 数据类型 变量名
3.3类中方法的定义
语法结构: 访问修饰符 返回值类型 方法名[参数]{ 代码块 }
3.4对象的定义
给某一个人或者某一件物定义名称
如:创建了一个人类,给他取名为:小明,小明拥有的功能和作用等
3.5对象的创建
类名 对象名 = new 类名();
3.6对象调用成员变量及方法
3.6.1 成员变量 VS 局部变量
成员变量:使用于类中,方法的外面的变量,并且系统会默认赋值,作用于整个类中。
整数类型 默认为0;浮点类型 默认为0.0; char类型 默认为空格(' '); Boolean类型 默认为false ; String类型默认为null
public class Test{ public static void main(String[] args){ Test01 t=new Test01(); t.name="姓名"; System.out.println(t.name); t.mehtod01(); } static class Test01{ String name; char sex; int age; public void mehtod01(){ double score=99.0; System.out.println("局部变量的成绩为"+score); } } }
局部变量: 作用于方法内的变量,系统不会赋予默认值,作用在方法中
3.6.2成员方法 VS 静态方法
成员方法:属于对象的方法,必须使用对象调用
静态方法:属于类的方法,使用类名调用
public class Test{ public static void main(String[] args){ Test t=new Test(); t.method01(); Test.method02(); } public void method01(){ System.out.println("这个是成员方法"); } public static void method02(){ System.out.println("这个是静态方法"); } }
3.6.3成员变量 VS静态变量
成员变量:属于对象的变量,每个对象独享一份
静态变量:属于类的变量,每个对象都共享一份
public class A{ //成员变量 String str1; //静态变量 static String str2; }
public class TestA{ public static void main(String[] args){ A a1=new A(); A a2=new A(); a1.str1="aaa"; a2.str1="bbb"; System.out.println(a1.str1); System.out.println(a2.str1); A.str2="ccc"; A.str2="ddd"; System.out.println(a1.str2); System.out.println(a2.str2); } }
4.构造方法
- 与类名相同的方法
- 没有返回项
4.1构造方法的定义
与类名相同,且没有返回项的方法
4.2构造方法的使用
- 和new在一起是创建对象
- 初始化属性
4.3构造方法的重载
public class Person{
String name;
char sex;
int age;
//构造方法
public Person(){}
//构造方法的重载
public Person(String name,char sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
}
}
4.4构造方法与普通方法的区别
构造方法:必须与类名相同,且没有返回项
普通方法: 可以与类名相同,可以有返回项
public class Person{ //注意:这种不是构造方法,而是成员方法 public void Person(){} }
二、面向对象特性之封装
1.private的使用
可以作用于方法、属性上,进行私有化
应用场景: 不让外界调用的属性和方法就使用private修饰
2.get/set方法的说明
get()方法,作用于得到私有化输出
set()方法,作用于设置私有化,以便get方法来得到数据
三、this关键字
代表本对象,this出现方法里,表示调用该方法的对象
this.属性/方法:调用本对象的成员变量/方法
this():调用本对象的构造方法(在一个构造方法中的第一句调用另外一个构造方法)
1.静态属性
静态属性属于类属性,该类所有的对象都共享该属性,静态属性直到项目结束才会被回收
注意:静态属性使用类名调用
static String name;
2.静态方法
public class A{ public static void main(String[] args){ A a=new A(); A.method(); } public static void method(){ System.out.println("静态方法"); } }
注意:静态方法只能使用类名调用;
3.静态代码块
静态代码块是类加载到方法区时才会被调用,该代码块只能初始化静态变量
代码块是创建对象时优先于构造方法调用,该代码块可以初始化成员变量和静态变量
构造方法是创建对象时调用,该方法可以初始化成员变量和静态变量
public class A{
static Sting name;
static {
name="xxx";//A.name
System.out.println("A的静态代码块")
}
}
四、继承
1.继承的概念
子类继承父类,一个子类只能有一个父类,一个父类可以有多个子类
2.类的继承的使用
多个类似的类,有相同的属性和方法,就可以把相同的属性和方法,抽取到父类,从而减少了代码的冗余性
创建子类对象,会不会调用父类构造方法?
会
创建子类对象,会不会创建父类对象?
不会
创建子类对象,为什么会调用父类构造方法?
目的是在子类对象中开辟空间用于存放父类的属性创建子类对象,先调用父类构造方法还是子类构造方法?
先调用子类构造方法创建子类对象,先完成父类构造方法还是子类构造方法?
先完成父类构造方法子类可以继承父类私有化的属性和方法吗?
可以继承,但是不可以直接调用,但是可以在父类中设置公有的方法,在公有的方法中调用私有的属性和方法,这叫做间接调用
3.继承中的构造方法
public class Person {
String name;
char sex;
int age;
public void eat(){
System.out.println("吃饭饭");
}
public void sleep(){
System.out.println("睡觉觉");
}
}
public class Chinese extends Person{
String chineseId;
public void playTaiJi(){
System.out.println("打太极");
}
}
public class Japanese extends Person{
String yearNumber;
public void playVideo(){
System.out.println("拍电影");
}
}
public class Test{
public static void main(String[] args) {
/**
* 知识点:继承
* 含义:子类继承父类的属性和方法
* 好处:减少代码冗余
* 应用场景:多个类中有相同的属性和方法,就抽取出放在父类里
*
* 需求:编写中国人、日本日
* 分析:
* 中国人 继承 人类:
* 属性:中国人的身份证
* 方法:打太极
* 日本人 继承 人类:
* 属性:年号
* 方法:拍电影
* 人类:
* 属性:姓名、性别、年龄
* 方法:吃饭饭、睡觉觉
*/
Chinese c = new Chinese();
//操作父类属性
c.name = "榮十一";
c.sex = '男';
c.age = 21;
System.out.println(c.name);
System.out.println(c.sex);
System.out.println(c.age);
//操作子类属性
c.chineseId = "1234567890";
System.out.println(c.chineseId);
//调用父类方法
c.eat();
c.sleep();
//调用子类方法
c.playTaiJi();
Japanese j = new Japanese();
//操作父类属性
j.name = "美田桜奈汾";
j.sex = '女';
j.age = 18;
System.out.println(j.name);
System.out.println(j.sex);
System.out.println(j.age);
//操作子类属性
j.yearNumber = "令和";
System.out.println(j.yearNumber);
//调用父类方法
j.eat();
j.sleep();
//调用子类方法
j.playVideo();
}
}
}
五、super关键字—父类
代表父类,作用于子类中:
super.属性/方法:调用父类非私有化的成员变量/方法
super():调用父类非私有化的构造方法
public class A { String str; public A() { } public void aMethod(){ System.out.println("A类的方法"); } } public class B extends A{ public B() { //调用父类的非私有化构造方法 super(); } public void method(){ //调用父类的非私有化属性 super.str = "xxx"; //调用父类的非私有化方法 super.aMethod(); } }
六、方法重写
含义:重写也叫做复写,将父类中的方法在子类中重新编写一遍
应用场景:父类方法不满足子类需求时,子类就可以重复父类的方法
条件:
七、访问修饰符
1.private 私有化的只允许本类访问
2.default 默认的只允许本类和本包的访问
3.protected 本类和本包以及其他包的子类可以访问
4.public 公共的 所有的均可以访问
八、Object类
含义: 基类也叫做超类,Object是所有类的祖先类
注意:如果一个类没有明确的继承父类,默认继承Object
1.equals()方法
比较两个对象的内存地址是否相同,Object不同的子类判断两个的对象是否相同有不同的判断规则,子类重写equals即可
public boolean equals(Object obj){ return this==obj; }
public class Test{ public static void main(Stringp[] args){ Object obj1=new Object();//0x001 Object obj2=new Object();//0x002 boolean equals=obj1.equalts(obj2) System.out.println(equalts);//false boolean bool==obj1==obj2; System.out.println(bool);//false } }
2.hashCod()方法
获取对象的hash值
/** hash值---系统利用对象的内存地址+散列算法获取的一个值 注意:hash值不等于内存值 */ @Override public int hashhCode(){ return Object.hash(username,password); }
public class User { private String username; private String password; public User() { } public User(String username, String password) { this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } User user = (User) obj; if(this.username.equals(user.username)){ return true; } return false; } @Override public String toString() { return username + " -- " + password; } }
知识点:switch使用字符串细节
两个字符串hash值有可能相同public class Test { public static void main(String[] args) { /** * 知识点:switch使用字符串细节 * * 两个字符串hash值有可能相同 */ String str = "ab"; switch (str) {//switch (str.hashCode()) { case "ab"://case 3104: if(str.equals("ab")){ System.out.println("ab"); } break; case "aa"://case 3105: if(str.equals("aa")){ System.out.println("aa"); } break; case "bC"://case 3105: if(str.equals("bC")){ System.out.println("bb"); } break; } } }
3.getClass()方法
获取类的字节码文件对象
public static void main(String[] args){ Object obj1=new Object(); Object obj2=new Object(); Class<? extends Object> c1=obj1.getClass(); Class<? extends Object> c2=obj2.getClass(); }
4.toString()方法
返回对象的字符串表示,Object不同的子类有不同的属性,重写toString,返回属性
//获取对象的字符表示(将对象转换为字符) public String toString(){ return getClass().getName()+"@"+Integer.toHexString(hashCode()); }
public class Test{ public static void main(String[] args) { User user1 = new User("1445584980", "123123"); User user2 = new User("1445584980", "123123"); System.out.println(user1.equals(user2));//true System.out.println(user1);//默认调用toString } }
九、final关键字--------最终
1.final修饰的类
不能被继承
2.final修饰的方法
该方法不能被重写
3.final修饰的属性
变成常量不能重新赋值
十、抽象类和抽象方法
抽象方法交给非抽象的子类去实现(重写)
应用场景:
当一个方法必须在父类中出现,但是这个方法又不好实现,就把该方法,交给非抽象的子类去实现
//抽象类 public abstract class 类名{ //抽象方法 public abstract void method(); }
面试题
抽象类不能有构造方法?抽象类可以有构造方法
抽象类中只能有抽象方法?抽象类中有非抽象方法(成员方法和静态方法)
抽象类中不可以没有抽象方法?抽象类中可以没有抽象方法,但是毫无意义
如果父类是抽象类,则子类必须实现父类的抽象方法?不一定,子类如果是抽象类,可以不实现父类的抽象方法
可以使用new关键字来创建抽象类对象?不可以,创建的是匿名内部类的对象
十一、接口
含义:特殊的抽象类
应用场景:接口更像一个规范
注意:
- JDK1.7时,接口中只能由静态常量和抽象方JDK
- JDK1.8开始,接口中有静态常量和抽象方法以及默认方法
- 接口是特殊的抽象类
作用:制定规范
//接口类 public interface I1{ //默认添加public static final int i=100;//静态常量,不可以修改 //默认添加abstract成为抽象类 public void method01(); public void method02(); //默认方法 default void defaultMethod(){ System.out.println("接口中的默认方法");//JDK1.8版本开始 } //静态方法 public static void staticMethod(){ System.out.println("接口中的静态方法"); } } //实现接口类 public class A implements I1{ @Override public void method01(){} @Override public void method02(){} } //测试类 public class Test{ public static void main(String[] args){ A a=new A(); a.defaultMethod(); I1.staticMethod(); } }
1.抽象类 VS 接口
抽象类:成员变量、静态变量、静态常量、成员方法、静态方法
接口:静态常量、静态方法、默认方法(JDK1.8)
- 相同之处:
- 可编译成字节码文件
- 不能创建对象
- 可以作为引用类型
- 具备Object类中所定义的方法
- 不同之处:
- 所有属性都是公开静态常量,隐式使用public static final修饰
- 所有方法都是公开抽象方法,隐式使用public abstract修饰
- 没有构造方法、动态代码块、静态代码块
2.深入接口 面试题:
- 一个类可以实现多个接口?可以
- 一个接口可以实现多个接口?不可以,接口与接口的关系是多继承
- 接口里面的方法不一定都是抽象的?JDK1.7时接口里只能有抽象方法,JDK1.8时接口可以有抽象方法和默认方法
- 接口解决了类的单继承问题?是的,因为类与类是单继承,类与接口是多实现
- 一个类是否可以继承一个类并同时实现多个接口?可以
- 接口可以new对象?接口是特殊的抽象类,但是本质还是抽象类,抽象类是不可以new对象的,接口也是不能new对象,new出来的匿名类内部类的对象
代码实现上述面试题功能:
//接口1 public interface I1{ public void i1Method01(); public void method01(); public void method02(){} } //接口2 public interface I2{ public void i2Method01(); public void method01(); public void method02(){} } //接口3 public interface I3{ public void i3Method01(); public void method01(); }//接口4 public interface I4{ public void i4Method01(); public void method01(); }//接口5 public interface I5{ public void i5Method01(); public void method01(); }//接口6 public interface I6{ public void i1Method01(); public void method01(); } //实现接口类 public class A extends Object implements I1,I2,I3{ @Override public void i2Method01{} @Override public void i1Method01{} @Override public void i4Method01{} @Override public void i5Method01{} @Override public void i3Method01{} //I1、I2中都有method01的抽象方法,在实现类中只实现一个 @Override public void method01(){} @Override public void method02(){ //在实现类中调用I1接口中的默认方法 //I1.super.method02(); I2.super.method02(); } } //测试类 public class Test{ //1.创建匿名类,实现I5接口中的i5method01方法 //2.创建匿名类的对象 //3.赋值给接口的引用 I5 i5=new I5(){ @Override public void i5Method01(){}; } }
3.类与接口的关系:
类-----类:单继承
类-----接口:多实现
接口–接口:多继承
4.接口的好处:
- 程序的耦合度降低
- 更自然的使用多态
- 设计与实现完全分离
- 更容易搭建程序框架
- 更容易更换具体实现
5.接口总结
- 什么是接口
- 从宏观上来看:接口是一种标准
- 从微观上来看:接口是一种能力和约定
- 接口与类的异同
- 没有构造方法,仅可定义公开静态常量与公开抽象方法
- 接口的应用
- Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口的扩充子类能力
- 接口的规范
- 任何类在实现接口时,必须实现接口种所有的抽象方法,否则此类为抽象类
- 实现接口种的抽象方法时,访问修饰符必须是public
- 什么是常量接口
- 将多个常量用于表示状态或固定值的变量,以静态常量的形式定义在接口中题一管理
- 什么是接口回调?
- 现有接口的使用者,后有接口的实现者
十二、多态
在面向对象中需要升级或者迭代时,进行修改数据,必须满足OCP原则,尽量不要改变以前的类,否则容易出现bug
OCP原则:
O—open:在需求升级或者迭代时,对于创建类是欢迎的
C----close:在需求升级或者迭代时,改变原有代码是拒绝的
P----principle:代表原则
1.类的多态
父类类名 引用=new 子类类名(); 引用.方法 —减少了代码的冗余,遵行了OCP原则
使用时,创建一个父类,用abstract抽象方法定义后,子类继承,测试类调用
//父类 public class Vehicle{ public abstract void start(); public abstract void stop(); } //子类1 public class Bike{ @Override public void start(){ System.out.println("自行车:控制好龙头,蹬踏板"); } @Override public void stop(){ System.out.println("自行车:捏手刹,刹车"); } } //子类2 public class Car{ @Override public void start(){ System.out.println("小汽车:点火,踩油门"); } @Override public void stop(){ System.out.println("小汽车:踩刹车和制动板,熄火停车"); } } //子类3: public class Plane{ @Override public void start(){ System.out.println("飞机:启动,当时速达到时,拉闸上飞"); } @Override public void stop(){ System.out.println("飞机:放下滑轮,减速,停机"); } } //测试类 public class Test{ public static void main(String[] args){ Vehicle v=new Bike(); Vehicle v1=new Car(); Vehicle v2=new Plane(); v.start(); System.out.println("风景动人!!!!"); v.stop(); System.out.println("-------------"); v1.start(); System.out.println("风景动人!!!!"); v1.stop(); System.out.println("-------------"); v2.start(); System.out.println("风景动人!!!!"); v2.stop(); System.out.println("-------------"); } }
2.接口的多态
1
//测试类 public class Test{ public static void main(String[] args){ Computer computer=new Computer(); //接口的多态:实现类的对象是指向接口的引用 //接口的引用中存放的是实现类对象在堆中开辟空间的地址 IUSB usb=new Keyboard(); IUSB usb1=new Mouse(); IUSB usb2=new Disk(); computer.connection(usb); computer.connection(usb1); computer.connection(usb2); } } //连接usb的方法 public class Computer{ public void connection(IUSB usb){ usb.use(); } } //接口 public interface IUSB{ public void use(); } //实现接口1 public class Disk implements IUSB{ @Override public void use(){ System.out.println("硬盘:上传下载文件"); } } //实现接口2 public class Mouse implements IUSB{ @Override public void use(){ System.out.println("鼠标:移动、左右点击"); } } //实现接口3 public class Keyboard implements IUSB{ @Override public void use(){ System.our.println("键盘:输入数据"); } }
十三、对象转型
1.向上转型
子类类型 转 父类类型:
- 可以调用父类非私有化属性
- 可以调用父类非私有化方法
- 可以调用子类重写父类的方法
- 不可以调用子类属性和方法
注意:向上转型就是多态
**多态的缺点:**不可以调用子类自己的属性和方法
//测试类 public class Test{ public static void main(String[] args){ A a=new B(); System.out.println(a.aAtrr); a.aMethod(); a.method(); } } //父类 public class A{ String aAtrr="父类属性"; public void aMethod(){ System.out.println("父类方法"); } public void method(){ System.out.println("父类方法"); } } //子类 public class B extends A{ String bAtrr="子类属性"; public void bMethod(){ System.out.println("子类方法"); } @Override public void mehthod(){ System.out.println("子类重写父类方法"); } }
2.向下转型
父类类型 转 子类类型
//测试类 public class Test{ public static void main(String[] args){ Animal an=new Dog();//向上转型 if(an instanceof Car){ Car car=(Car) an;//向下转型 car.shout(); }else if(an instanceof Dog){ Dog dog=(Dog) an;//向下转型 dog.eat(); } } } //父类 public class Animal{ } //子类1 public class Car extends Animal{ public void shout(){ System.out.println("喵喵喵~~~~"); } } //子类2 public class Dog extends Animal{ public void eat(){ System.out.println("吃骨头!"); } }
注意:
向下转型转不好就会出现ClassCasteException—类型转换异常
向下转型一定要使用instanceof判断
//类 public class MyString{ private String value; public MyString(String value){ this.value=value; } @Override public boolean equalts(Object obj){ if(this==obj){ return true; } if(obj instanceof MyString){ Mystring m=(MyString) obj; //['a','b','c'] char[] v1=this.value.toCharArray();//把当前对象的str转换为字符组 //['a','b','c'] char[] v2=m.value.toCharArray();//把当前对象的str转换为字符数组 if(v1.length!=v2.length){ return false; } for(int i=0;i<v2.length;i++){ if(v1[i]!=v2[i]){ return false; } } return true; } return false; } @Override public String toString(){ return value; } } //测试类 public class Test{ public static void main(String[] args){ String str1 = new String("abc"); String str2 = new String("abc"); System.out.println(str1 == str2);//false System.out.println(str1.equals(str2));//true - 比较两个字符串内容是否相同 System.out.println(str1);//默认调用toString System.out.println(str2);//默认调用toString System.out.println("--------------"); MyString m1 = new MyString("abc"); MyString m2 = new MyString("abc"); System.out.println(m1 == m2);//false System.out.println(m1.equals(m2)); System.out.println(m1); System.out.println(m2); } }
十四、内部类
应用场景:
内部类的应用场景:
如果一个类的对象只在另外一个类中使用。就可以考虑把该类变成成员内部类或者静态内部类。
如果内部类要用到外部类的所有属性就把该类变成成员内部类
如果内部类只用到外部类的静态类就把该类变成静态内部类
如果一个类的对象只在另外一个类的方法中使用,就可以把该类变成局部内部类,一般不适用这种设计思想
如果一个类的对象只在接口中使用,就可以考虑把该类变成接口内部类,一般不适用这种设计思想
抽象类子类的对象或者是接口实现类对象只使用到一次,就可以考虑使用匿名内部类
1.成员内部类
特点:可以调用外部类中的所有属性
//外部类 public class Outter{ private String str="aaa"; default String str1="bbb"; protected String str2="ccc"; public String str3="ddd"; final String str4="eee"; static String str5="fff"; //成员内部类 class Inner{ private String str1="成员内部里的属性"; public void method{ System.out.println("成员内部类里的方法"); System.out.println(this.str); System.out.println(Outter.this.str);//调用外部类属性 System.out.println(str1);//Outter.this.str1 System.out.println(str2);//Outter.this.str2 System.out.println(str3);//Outter.this.str3 System.out.println(str4);//Outter.this.str4 System.out.println(str5);//Outter.this.str5 } } } //测试类 public class Test{ public static void main(String[] args){ //创建成员内部类对象 Outter.Inner inner=new Outter().new Inner(); //调用方法 inner.method(); } }
2.静态内部类
特点:只能调用外部类的静态属性
//外部类 public class Outter{ private String str="aaa"; default String str1="bbb"; protected String str2="ccc"; public String str3="ddd"; final String str4="eee"; static String str5="fff"; //静态内部类 static class Inner{ public void method{ System.out.println("静态内部类里的方法"); System.out.println(str5);//Outter.this.str5 } } } //测试类 public class Test{ public static void main(String[] args){ //创建静态内部类对象(不用创建外部类对象) Outter.Inner inner=new Outter.Inner(); //调用方法 inner.method(); } }
3.接口内部类
注意:接口内部类底层就是静态内部类
/外部类 public class Outter{ //接口内部类默认添加public static class Inner{ public void method{ System.out.println("接口内部类里的方法"); } } } //测试类 public class Test{ public static void main(String[] args){ //创建接口内部类对象 Outter.Inner inner=new Outter.Inner(); //调用方法 inner.method(); } }
4.局部内部类
/外部类 public class Outter{ public void function{ //局部内部类 class Inner{ public void method{ System.out.println("局部内部类里的方法"); } } //创建局部内部类的对象 Inner inner=new Inner(); //调用方法 inner.method(); } } //测试类 public class Test{ public static void main(String[] args){ //创建外部类对象 Outter.Inner outter=new Outter(); //调用方法 outter.function(); } }
在局部内中使用到变量时,JDK1.8版本开始自动变成常量
即默认添加了public static final
//测试类 public class Test{ public static void main(String[] args){ //创建外部类的对象 Outter outter=new Outter(); //调用方法 Object obj=outter.function(); System.out.println(obj); } } //外部类 public class Outter{ public Object function(){ /** 如果局部内部类中使用到该变量,JDK1.8开始变量自动编程常量 因为防止i在该方法结束后才会使用 由于当function()方法在栈中使用结束后,function()方法被销毁后,但是需要在main中将obj进行调用i时;当i为变量时,在function()方法中直接被销毁了,无法调用。故只能默认添加final将i变成常量,从而i在堆中的常量池中,只有程序结束以后,常量池才能被销毁,以此来保证i的存活时间更久,避免bug。 */ int i=100;//默认添加final //局部内部类 class Inner{ @Override public String toString{ return i+""; } } //创建局部内部类的对象 Inner inner=new Inner(); return inner; } }
5.匿名内部类
//抽象类 public abstract class A{ public abstract void method(); } //接口类 public interface I1{ public void method(); } //测试类 public class Test01{ public static void main(String[] args){ //1.创建匿名子类,继承A,重写method //2.创建匿名子类对象,赋值给父类的引用 A a=new A(){ @Override public void method(){} }; } } //测试类2 public class Test02{ public static void main(String[]args){ //1.创建匿名实现类,实现I1中的method //2.创建匿名实现类的对象,指向接口的引用 I1 i1=new I1(){ @Override public void method(){} }; } }