Day12

一、多态

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;
			}
            
            ......
                
        }
上一篇:c语言_Day12_07_11


下一篇:【学习笔记】 unity基础_Day12