一、多态
1、需求:老师骑着自行车上班
分析:老师类、自行车类
public class Teacher { public void open(Bick v){ v.start(); } public void close(Bick v){ v.stop(); } } public class Bick{ @Override public void start(){ System.out.println("自行车:握好扶手,踩下脚踏板"); } @Override public void stop(){ System.out.println("自行车:捏手刹~~~"); } }
2、需求升级/迭代:自行车->小汽车
步骤:
①.创建Car类,编写start、stop
②.在原有Teacher类的基础上编写open、close
public class Car{ @Override public void start(){ System.out.println("小汽车:一键启动,踩下油门"); } @Override public void stop(){ System.out.println("小汽车:踩刹车,熄火~~"); } } public class Teacher { public void open(Bick v){ v.start(); } public void close(Bick v){ v.stop(); } public void open(Car v){ v.start(); } public void close(Car v){ v.stop(); } }
注意:违反了OCP原则
3、OCP - 开闭原则:
O - open :在需求升级时,对于创建类是欢迎的
C - close:在需求升级时,改变原有代码是拒绝的
注意:需求升级时,尽量不要改变以前的类,否则容易出bug
4、需求升级/迭代:自行车->小汽车->飞机
步骤:创建Plane类继承Vehicle
public abstract class Vehicle { public abstract void start(); public abstract void stop(); } public class Plane extends Vehicle{ @Override public void start() { System.out.println("飞机:一键启动,加油门,拉机翼~~~"); } @Override public void stop() { System.out.println("飞机:跳伞~~~"); } } public class Test01 { public static void main(String[] args) { Teacher t = new Teacher(); //类的多态:子类对象指向父类引用 //父类引用中存储的是子类对象在堆中的地址 Vehicle v = new Plane(); t.open(v); System.out.println("欣赏沿途的风景..."); t.close(v); } }
5、需求:鼠标、硬盘连接电脑
public interface IUSB { public void use(); } public class Disk implements IUSB{ @Override public void use() { System.out.println("硬盘:上传文件、下载文件"); } } public class Mouse implements IUSB{ @Override public void use() { System.out.println("鼠标:左点点,右点点"); } } public class Computer { //连接usb的方法 public void connection(IUSB usb){ usb.use(); } } public class Test01 { public static void main(String[] args) { Computer computer = new Computer(); //接口的多态:实现类的对象指向接口的引用 //接口的引用中存放的是实现类对象在堆中开辟空间的地址 IUSB usb = new Keyboard(); computer.connection(usb); } }
二、对象转型
1.向上转型:子类类型 转 父类类型
可以调用父类非私有化属性
可以调用父类非私有化方法
可以调用子类重写父类的方法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 method(){ System.out.println("子类重写父类的方法"); } } A a = new B(); System.out.println(a.aAtrr);//父类属性 a.aMethod(); //父类方法 a.method(); //子类重写父类的方法
不可以调用子类属性和方法
注意:向上转型就是多态
多态的缺点:不可以调用子类自己的属性和方法
2.向下转型:父类类型 转 子类类型
注意:
向下转型转不好就会出现 ClassCastException - 类型转换异常
向下转型一定要使用 instanceof 判断public class Test01 { public static void main(String[] args) { Animal an = new Cat();//向上转型 if(an instanceof Cat){//判断an引用指向的对象是否是Cat类型 Cat cat = (Cat) an;//向下转型 cat.shout(); }else if(an instanceof Dog){//判断an引用指向的对象是否是Dog类型 Dog dog = (Dog) an;//向下转型 dog.eat(); } } }
3、String底层源码
String的equals为什么可以判断字符串内容?
底层把String的内容转换为字符数组,依次比较ASCII码@Override public boolean equals(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; }
三、内部类
含义:一个类里面声明一个类
1.成员内部类
特点:可以调用外部类中所有的属性
//外部类 public class Outter { private String str1 = "aaa"; String str2 = "bbb"; protected String str3 = "ccc"; public String str4 = "ddd"; final String str5 = "eee"; static String str6 = "fff"; //成员内部类 class Inner{ private String str1 = "成员内部里的属性~~~"; public void method(){ System.out.println("成员内部类里的方法"); System.out.println(this.str1); System.out.println(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 System.out.println(str6);//Outter.str6 } } } //创建成员内部类对象 Inner inner = new Outter().new Inner(); //调用方法 inner.method();
2.静态内部类
特点:只能到调用外部类的静态属性
//外部类 public class Outter { private String str1 = "aaa"; String str2 = "bbb"; protected String str3 = "ccc"; public String str4 = "ddd"; final String str5 = "eee"; static String str6 = "fff"; //静态内部类 static class Inner{ public void method(){ System.out.println("静态内部类里的方法"); //静态内部类不能调用外部类的成员变量 // System.out.println(str1); // System.out.println(str2); // System.out.println(str3); // System.out.println(str4); // System.out.println(str5); System.out.println(str6);//Outter.str6 } } } //创建静态内部类对象(不用创建外部类对象) Inner inner = new Outter.Inner(); //调用方法 inner.method();
3.接口内部类
//接口 public interface Outter { //接口内部类 默认添加public static class Inner{ public void method(){ System.out.println("接口内部类里的方法"); } } } //创建接口内部类对象 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(); } }
5.匿名内部类
//创建匿名内部类 List list = new List() { @Override public int size() { // TODO Auto-generated method stub return 0; } ...... }