day_12 多态、Object、抽象、接口

1.多态

1.1相关知识

/**
 * 软件设计六大原则
 * 		1 单一职责原则:功能单一,只拥抱一种变化
 * 			一个方法只负责一件事,这样该方法进行改动的时候,不会影响其他程序,几乎所有程序员都在遵循这个原则
 * 			优点:降低类之间的耦合度,提高可读性,增加可维护性和可扩展性,降低可变性的风险
 * 		2 里氏替换原则:所有可以使用父类的地方,一定可以使用子类
 * 		3 依赖倒置原则:高层通过抽象依赖底层,细节应该依赖于抽象
 * 		4 接口隔离原则:客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。
 * 		5 迪米特原则:也称为知识最少原则
 * 			一个类尽量减少自己对其他类的依赖,原则就是低耦合,高内聚
 * 		6 开闭原则:对修改关闭,对扩展开放
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午6:45:57
 */

1.2是什么

/**
 * 变量声明:数据类型 变量名 = 值;
 * 
 * 多态:父类引用指向子类对象
 * 		父类引用:使用父类生命的引用类变量
 * 		指向:就是通过这个变量可以找到谁
 * 		使用父类声明的变量,可以找到子类对象
 * 		Animal a = new Animal();
 * 		Animal a = new Cat();多态
 * 
 * 多态的几种形式
 * 		1 直接多态 Animal a = new Cat();
 * 		2 形参和实参:方法声明时,参数列表需要接受父类类型,而方法调用时,传入子类对象
 * 			public static void m1 (Animal a){}
 * 			m1(new Cat());
 * 		3 返回值:返回值类型是父类类型,但是返回的对象是子类对象
 * 			public static Animal m2(){
 *				return new Cat();
 *			}
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午6:45:57

1.3缺点

/**
 *多态缺点:丢失子类特有的属性
 *使用多态进行调用
 *		1 如果父类没有,不管子类有没有,都会报错,因为丢失子类特有属性
 *		2 如果父类有,子类没有,使用父类的,因为继承
 *		3 如果父类有,子类也有,除了成员方法执行子类,其他都执行父类的(因为成员方法可以覆写)
 *
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午6:45:57
 */

1.4怎么用

package day_12text;

public class Text01 {
	public static void main(String[] args) {
		//多态
		Animal a = new  Cat();
		a.walk();
	}
}
//动物父类
class Animal{
	public void walk() {
		System.out.println("行走方式...");
	}
}
//猫子类继承动物父类
class Cat extends Animal{
	public void walk() {
		System.out.println("猫起飞");
	}
}
package day_12text;

public class Text02 {
	public static void main(String[] args) {
		// 直接创建变量进行多态
		SupClass sup1 = new SubClass();
		// 形参和实参多态 方法调用时,传入子类对象
		m1(new SubClass());
		// 返回值 返回的对象是子类对象
		SupClass sup2 =m2();
	}
	//形参实参 参数列表需要接受父类类型
	public static void m1(SupClass sup){
	}
	//返回值 返回值类型是父类类型
	public static SupClass m2(){
		return new SubClass();
	}
}
//Sup父类
class SupClass {

}
//Sub子类
class SubClass extends SupClass {

}

1.5优点

package day_12text;
/**
 * 多态好处
 * 		高内聚,低耦合
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午7:20:33
 */
public class Text03 {
	public static void main(String[] args) {
		//直接创建变量进行多态
		Cat_01 c = new Cat_01();
		walk(c);
		Dog_01 d = new Dog_01();
		walk(d);
		Pig p = new Pig();
		walk(p);
	}

	// 需求 : 要求能够接收所有的动物对象,并调用对象的walk方法
	// 这种写法,后续想要养别的宠物,这里源码需要改动
	// public static void walk(Cat_01 c) {
	// c.walk();
	// }
	// public static void walk(Dog_01 d) {
	// d.walk();
	// }
	
	// 多态写法,只要是动物的子类,都可以接收,所以后续想养其他宠物,这里也不需要更改代码,拥抱多种变化
	public static void walk(Animal_01 a) {
		a.walk();
	}
}
class Animal_01 {
	public void walk() {
		System.out.println("动物走路");
	}
}

class Cat_01 extends Animal_01 {
	int age = 2;

	public void walk() {
		System.out.println("猫起飞");
	}
}

class Dog_01 extends Animal_01 {
	int age = 3;

	public void walk() {
		System.out.println("狗刨");
	}
}

class Pig extends Animal_01 {
	@Override
	public void walk() {
		System.out.println("猪滚");
	}
}

1.6隐秘多态

package day_12text;
/**
 * 隐秘多态
 * 总结 : 通过子类,调用了父类的方法的时候,父类的这个方法的上下文环境,就是多态环境(属于父类空间,子类对象)
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午7:30:01
 */
public class Text04 {

	public static void main(String[] args) {
		Sup sup = new Sub();
		// 2
		System.out.println(sup.i);
		// 子类的m2
		sup.m2();

		Sub sub = new Sub();
		// 3
		// System.out.println(sub.i);
		//子类
		// sub.m2();
		sub.m1();
	}
}
class Sup {
	int i = 2;
	public void m1() {
		// this : 保存当前类对象的内存地址
		// 当前类 : this出现在哪个类,哪个类就是当前类  并且 this是第一个成员变量,既然是变量,肯定有数据类型
		// this的类型是当前类类型(Sup) 或者父类类型的时候可以存储当前类对象的地址
		// 如果是父类类型,说明发生了多态,会丢失特有属性,但是this可以调用当前类中所有的属性,所以this是当前类类型
		// Sup this;
		
		// this : 用在成员方法中,哪个对象调用了这个方法,this就指向哪个对象 在这里 m1是sub对象调用的,所以this 就指向 sub对象
		// 而 sub是继承了Sup的 所以 等于是Sup this = sub;   Sub sub = new Sub();  所以  Sup this = new Sub(); 
		// 所以在这里 this 发生了多态
		System.out.println(this.i);
		this.m2();
	}

	public void m2() {
		System.out.println("父类的m2");
	}
}

class Sub extends Sup {
	int i = 3;

	public void m2() {
		System.out.println("子类的m2");
	}
}

1.7Instanceof

/**
 * 多态又叫向上转型
 * 子类到父类 是向上转型 , 父类到子类是向下转型
 * 
 * 为什么需要向下转型
 * 因为多态会丢失子类特有的属性,想要调用子类特有属性的时候,需要转换为对应的子类类型才行
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午7:40:02
 */
package day_12text;

public class Text05 {
	public static void main(String[] args) {
		Animal_01 a = new Cat_01();
		// 调用不了,丢失特有属性
		// System.out.println(a.age);
		m1(a);
		a = new Dog_01();
		m1(a);
	}

	public static void m1(Animal_01 a) {
		// instanceof : 判断某个对象是否由某个类实例化而来
		//如果a是类Cat_01的对象
		if (a instanceof Cat_01) {
			//转换为对应的子类类型
			Cat_01 c = (Cat_01) a;
			System.out.println(c.age);
		} else {
			//转换为对应的子类类型
			Dog_01 c = (Dog_01) a;
			System.out.println(c.age);
		}
	}
}

1.8错误

package day_12text;

public class Text06 {

	public static void main(String[] args) {
		Animal_01 a = new Cat_01();
		// 调用不了,丢失特有属性
		// System.out.println(a.age);
		m1(a);
		// 假如传递一个Dog类型,就会报错
		a = new Dog_01();
		m1(a);
	}
public static void m1(Animal_01 a){
	Cat_01 c =(Cat_01)a;
	System.out.println(c.age);
}
}

 2.Abstract

2.1是什么

/**
 * 抽象类往往用来表示设计中得到的抽象概念
 * 比如动物 , 它就只是一个抽象的概念,并没有一个东西叫动物,没有对应的实体,这种情况下,适合把它定义为抽象类
 * 
 * abstract 是个修饰符
 * 		修饰的类是抽象类, 不能创建对象,只是用于被继承
 * 		修饰的方法是抽象方法,并且该方法没有方法体(也就是{})
 * 		抽象方法必须在抽象类中,但是抽象类中不一定有抽象方法
 * 
 * abstract和final 是二选一 , 因为final修饰的类不能被继承,成员方法不能被覆写
 * 		而 abstract修饰的抽象类就是用来被继承的,抽象方法就是用来被覆写实现的
 * 
 * 一个非抽象类 继承一个抽象类,需要实现所有的抽象方法
 * 一个抽象类继承一个抽象类 需要实现0~N个抽象方法
 * 
 * 抽象类虽然不能创建对象,但是有构造方法,用于子类创建对象时调用
 * 
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午8:00:52
 */

2.2怎么用

package day_12text;

public class Text07 {
	public static void main(String[] args) {
		// Animal animal = new Animal();
		Animal_02 a = new Cat_02();
		a.walk();
		Animal_02 d = new Dog_02();
		d.walk();
	}
}

//不能创建对象,只是用于被继承
abstract class Animal_02{
	public Animal_02(){
		System.out.println("父类构造");
	}
	public abstract void walk();
}

class Cat_02 extends Animal_02{
	public void walk() {
		System.out.println("猫起飞");
	}
}

class Dog_02 extends Animal_02{
	public void walk() {
		System.out.println("狗刨");
	}
}
package day_12text;

public class Text08 {
	
}
abstract class A {
	public abstract void m1();

	public abstract void m2();

	public abstract void m3();
}

// 非抽象类继承抽象类
class B extends A {

	@Override
	public void m1() {
		// TODO Auto-generated method stub

	}

	@Override
	public void m2() {
		// TODO Auto-generated method stub

	}

	@Override
	public void m3() {
		// TODO Auto-generated method stub

	}
}

// 抽象类继承抽象类需要实现0~N个抽象方法
abstract class C extends A {
	@Override
	public void m1() {

	}
}

class D extends C {
	//覆写与实现并无本质区别
	@Override
	public void m1() {
		// TODO Auto-generated method stub

	}
	//实现
	@Override
	public void m2() {
		// TODO Auto-generated method stub

	}
	//实现
	@Override
	public void m3() {
		// TODO Auto-generated method stub

	}

}

2.3注意

abstract和final不能同时存在

3.Interface

3.1是什么

/**
 * interface : 定义接口关键字   语法 : [权限修饰符] interface 接口名 { 类体 }
 * 
 * 接口主要为了解决java中单继承功能变弱问题,一个类只能继承一个类,但是可以实现多个接口
 * 1.8之前 接口是完全抽象的,只能有抽象方法和常量
 * 1.8开始 接口中允许出现默认方法和静态方法
 * 
 * 1 语法  [权限修饰符] interface 接口名 { 类体 }
 * 2 接口中默认都是public的
 * 			接口中的变量都是常量,并且 public static final 可以省略,默认就是
 * 			接口中的抽象方法,public abstract 可以省略,默认就是
 * 3 接口没有构造方法,同时不能创建对象
 * 4 一个类只能继承一个类,但是可以实现多个接口
 * 			[权限控制修饰符] class 类名 implements 接口名1,接口名2,....{}
 * 			一个类实现接口,必须实现接口中所有的抽象方法
 * 			一个抽象类,实现接口,需要实现0~N个抽象方法
 * 5 接口和接口之间 是多继承,多个以逗号隔开
 * 		[权限控制] interface 接口名 extends 父接口名1, 父接口名2,....{}
 * 
 * 6 1.8开始 可以有静态方法和default方法(default方法就可以理解为成员方法,子实现类也可以覆写)
 * 			静态方法调用 : 接口名.方法名(参数);
 * 			默认方法调用 : 需要用 子实现类对象.方法名(参数); 
 * 	   1.9 开始 就开始支持private方法
 *
 * @author 学到头秃的张张张
 *@Date 2021年10月14日下午8:20:24
 */
package day_12text;

public interface Text09 {
	// 接口中没有变量,只有常量
	public static final int xxx = 2;
	// public static final 可以省略,默认就是
	int aaaa = 3;

	// 抽象方法
	public abstract void m1();

	// public abstract 可以省略,默认就是
	void m2();

	// 静态方法
	public static void m3() {
		System.out.println("静态方法");
	}

	// 默认方法
	default void m4() {
		System.out.println("默认方法");
	}
}
interface H{
	void m1();
}
interface I{
	void m2();
}
interface J{
	void m3();
}
interface K extends H,I,J{
	void m4();
}
class L  implements H,J{

	@Override
	public void m3() {
	}
	@Override
	public void m1() {
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值