多态
类的多态:子类对象指向父类引用
父类引用中存储的是子类对象在堆中的内存地址接口的多态:实现类对象指向接口的引用
接口的引用中存储的是实现类对象在堆中开辟的地址设计原则:前人给我们总结的经验,告诉我们不要做什么
设计模式:前人给我们总结的经验,特定的需求下我们应该怎么一步一步的去做优点:在需求升级时,不违反ocp原则;
缺点:不可以调用子类独有的属性和方法
需求:学生乘坐飞机去旅游
创建Vehicle父类:
public abstract class Vehicle { public abstract void open(); public abstract void close(); }
创建Plan(飞机)子类继承Vehicle父类:
public class Plan extends Vehicle{ @Override public void open() { System.out.println("飞机:起飞........") } @Override public void close() { System.out.println("飞机:降落........."); } }
创建Student学生类:
public class Student { public void open(Vehicle vehicle) { vehicle.open(); } public void close(Vehicle vehicle) { vehicle.close(); } }
创建Test测试类:
public class Test{ public static void main(String[] args) { //多态:子类的对象指向父类的引用 Vehicle vehicle = new Plan(); student.open(vehicle);//打印:飞机:起飞........ student.close(vehicle);//打印:飞机:降落......... } }
内部类
分类:
成员内部类 Outter I n n e r . c l a s s 静态内部类 O u t t e r Inner.class 静态内部类 Outter Inner.class静态内部类OutterInner.class
接口内部类 Outter$Inner.class
局部内部类 Outter$1Inner.class
匿名内部类 Test01$1.class//外部类 public class Outter { String str1 = "成员变量"; //成员内部类 class Inner01{} static String str2 = "静态变量"; //静态内部类 static class Inner02{} private void method() { //局部变量 String str3 = "局部变量"; //局部内部类 class Inner03{} } }
//外部接口 public interface IOutter { //接口内部类 class Inner{} }
应用场景:
B类的对象只在A类中使用,并且B类使用到A类所有的属性,就可以将B类设置为A类的成员内部类
B类的对象只在A类中使用,并且B类使用到A类的静态属性,就可以将B类设置为A类的静态内部类
B类对象只在I1接口中使用,就可以将B类设置为I1接口的接口内部类
B类对象只在A类的method方法中使用,就可以将B类设置为A类method方法中的局部变量
抽象类的子类或者接口的实现类只new了一次对象,就直接使用匿名内部类即可
成员内部类
需求:创建成员内部类的对象,并调用方法
//外部类 public class Outter { private String str1 = "属性1"; String str2 = "属性2"; protected String str3 = "属性3"; public String str4 = "属性4"; final String str5 = "属性5"; static String str6 = "属性6"; static final String str7 = "属性7"; //成员内部类 class Inner{ String str1 = "内部类属性"; String str7 = "内部类属性7"; public void method() { System.out.println("调用成员内部类的方法"); System.out.println(str1);//内部类属性 System.out.println(Outter.this.str1); System.out.println(str2); System.out.println(str3); System.out.println(str4); System.out.println(str5); System.out.println(str6); System.out.println(str7); System.out.println(Outter.str7); } } }
创建测试类
package com.qf.outter_inner_03; import com.qf.outter_inner_03.Outter.Inner; public class Test { /** * 注意:创建成员内部类必须先创建外部类对象 */ public static void main(String[] args) { Inner inner = new Outter().new Inner(); inner.method(); } }
静态内部类
需求:创建静态内部类的对象,并调用方法
创建静态内部类:
package com.qf.outter_inner_04; public class Outter { static String str1="属性1"; static final String str2 = "属性2"; //静态内部类 static class Inner{ public void method() { System.out.println("调用静态内部类的方法"); System.out.println(str1); System.out.println(str2); } } }
创建测试类:
package com.qf.outter_inner_04; import com.qf.outter_inner_04.Outter.Inner; public class Test01 { /** * 注意:创建静态内部类不用创建外部类对象,直接外部类.内部类() * * 小结:静态内部类只能调用外部类的静态属性,不能调用外部类的成员属性 * * 面试题:静态内部类为什么不能调用外部类的成员属性 * 答:因为创建静态内部类对象不会创建外部类对象,所以外部类的成员属性不会在内存中得到体现 */ public static void main(String[] args) { Inner inner = new Outter.Inner(); inner.method(); } }
接口内部类
需求:创建接口内部类的对象,并调用方法
创建接口:
package com.qf.outter_inner_05; //外部接口 public interface Outter { class Inner{ public void method() { System.out.println("调用接口内部类的方法"); } } }
创建测试类:
package com.qf.outter_inner_05; import com.qf.outter_inner_05.Outter.Inner; public class Test01 { /** * 需求:创建接口内部类的对象,并调用方法 * 注意: * 1.接口内部类的使用和静态内部类一样 * 2.接口内部类系统会使用public static修饰 * */ public static void main(String[] args) { Inner inner = new Outter.Inner(); inner.method(); } }
局部内部类
需求:调用局部内部类的方法
创建局部内部类:
//外部类 public class Outter { public void outterMethod(){ //外部类的局部变量,在局部内部类中使用了,JDK1.8开始会自动将该变量设置为常量 //外部类的局部变量,在局部内部类中使用了,JDK1.8之前必须手动设置该变量为常量 int i = 100; class Inner{ public void innerMethod(){ System.out.println("调用局部内部类中的方法 -- " + i); } } Inner inner = new Inner(); inner.innerMethod(); } }
创建测试类:
public class Test01 { public static void main(String[] args) { Outter outter = new Outter(); outter.outterMethod(); } }
匿名内部类:
创建抽象类A:
public abstract class A { public abstract void method(); }
创建测试类:
创建的是匿名内部类对象
步骤:
1.创建匿名类(Test01$1.class),继承A类,重写method方法
2.创建匿名对象
3.将匿名对象赋值给父类的引用 – 多态public class Test { public static void main(String[] args) { A a = new A() { @Override public void method() { System.out.println("用良心做教育"); } }; a.method(); } }