2022.01.12_Java学习总结_面向对象_3_Final、多态、abstract、Interface、Object

1. Final

1.1 是什么

* final 是个修饰符,表示最终的,不可更改的

1.2 能做什么

 * final修饰的类 不能被继承
 * 
 * final修饰的成员方法 不能被覆写
 * 
 * final修饰的变量 不能二次赋值,没有默认值,必须显式赋值
 * 
 * 一般我们把final修饰的静态变量叫做常量,也就是 public static final 数据类型 变量名 =;

1.3 怎么用

// final 修饰的类 不能被继承
 final class A{
 }
 class B extends A{
 }

// final修饰的成员方法 不能被覆写
 class A {
	 public final void m1() {
	 }
 }
 class B extends A{
	 @Override
	public void m1() {
	 }
 }
 
	// final修饰的变量 不能二次赋值
	final int i = 2;
	i=3;

	// final 修饰的成员变量 没有默认值,并且不能二次赋值
	 final int age ;
	
	// final修饰的静态变量,没有默认值,不能二次赋值,一般 psf会一起出现,简称常量
	// 常量名 建议全部大写
	public final static int AGE=18;

1.4 修饰引用类型

在这里插入图片描述

2. 多态

2.1 是什么

父类引用指向子类对象
父类引用 : 指的是 用父类型声明的引用类型变量
指向 : 通过内存地址可以找到哪个对象
子类对象 : new 子类 创建的堆内存对象
子类 变量 = new 子类();
Cat c = new Cat();
父类类型 变量名 = new 子类();
Animal a = new Cat();

2.2 相关知识

软件设计六大原则 : 
1 单一职责原则 : 功能单一,只拥抱一种变化
2 里氏替换原则 : 能使用父类的情况下,一定可以使用子类
  因为继承,父类有的功能,子类都有
3 依赖倒置原则 : 细节应该依赖抽象,而抽象不应该依赖细节
4 接口隔离原则 : 先不管
5 迪米特法则 : 最少知识原则,和其他类或对象,尽可能有更少的了解
6 开闭原则 : 对修改关闭,对扩展开放

2.3 优点

同一操作,作用于不同对象,可以有不同的解释,产生不同的结果,这就是多态性

当一件事会有多种不同实现方式的时候,我们选择依赖高层,来拥抱多种变化
本质还是降低类和细节之间的耦合度

	// 需求 : 要求能够接收Cat对象,并调用该对象的eat方法
	   public static void test(Cat cat){
	   cat.eat();
	   }
	//
	//  新增需求 : 要求能够接收Dog对象,并调用该对象的eat方法
	   public static void test(Dog dog){
	   dog.eat();
	   }

	// 需求 : 要求能够接收所有的动物,并调用该对象的eat方法
	public static void test(Animal a) {
		a.eat();
	}

2.4 缺点


丢失子类特有的属性

2.5 使用语法

public static void main(String[] args) {
		Cat c = new Cat();
		// 多态
		Animal a = new Cat();
		a.eat();
		a = new Dog();
		a.eat();
	}
* 多态的缺点 : 丢失子类特有的属性
 * 
 * 多态进行属性调用 : 
 * 
 * 		1 如果父类没有 ,直接报错,不管子类有没有 
 * 	
 * 		2 如果父类有,子类没有, 直接执行父类 
 * 
 * 		3 父类和子类都有, 成员方法执行子类,因为成员方法可以覆写,其他的都执行父类
 * 
 * 多态又叫向上转型
public static void main(String[] args) {
		// 多态
		SupClass sup = new SubClass();
		// 父类和子类都有的成员方法 , 执行子类
		sup.m1();
		// 父类没有,子类有,报错,访问不了
		// sup.m2();
		// 父类有,子类没有,执行父类
		sup.m3();
		// 父类和子类都有的 静态方法  执行父类
		sup.m4();
		// 成员变量,也是执行父类
		System.out.println(sup.i);
		
		// 此时 由于多态原因,子类特有属性访问不到,想要访问也行,先进行向下转型
		// 必须先发生向上转型,才能发生向下转型
		SubClass sub = (SubClass) sup;
		sub.m2();
		
		// 没有发生向上转型,如果直接使用向下转型 会报错
		SupClass sup1 = new SupClass();
		// 类型转换异常
		SubClass sub1 = (SubClass) sup1; 
		}

类型转换异常
在这里插入图片描述

2.6 多态的几种形式

 * 多态的几种形式
 * 
 * 父类引用 指向 子类对象

	public static void main(String[] args) {
		// 1 直接多态
		Sup sup = new Sub();
		// 2 形参和实参,方法参数列表为父类类型,调用方法传入子类对象
		m1(new Sub());
		// 3 返回值多态,返回值类型是父类类型,但是返回子类对象
		Sup result = m2();

	}

	public static Sup m2() {
		return new Sub();
	}

	public static void m1(Sup sup) {

	}

2.7 Instanceof

		// instanceof : 判断 某个对象是否由某个类实例化而来
		if ( sup1 instanceof SubClass) {
			// 如果是 在向下转型,不是就不转,可以避免类型转换异常
			SubClass sub1 = (SubClass) sup1;
		}

3. abstract

3.1 是什么

* abstract : 修饰符,修饰的类 是抽象类,修饰的方法是抽象方法
 * 
 * 抽象类,不能实例化对象
 * 
 * 抽象方法,没有方法体,只定义功能,没有功能的实现,并且抽象方法必须在抽象类中
 * 
 * 反之,抽象类中,可以没有抽象方法
 * 
 * abstract不能和final 同时出现

3.2 使用语法

abstract class Animal {
	/**
	 * 动物吃饭的功能
	 */
	public abstract void eat();
	public void m1() {

	}
}

class Cat extends Animal {

	// 实现
	@Override
	public void eat() {

	}
}

4. Interface

4.1 是什么

 * 接口 可以理解为完全抽象的一个类,里面只有抽象方法和常量
 * 
 * 但是从1.8开始,允许出现 静态方法和默认方法
 * 
 * 语法 修饰符 interface 接口名 {}
 * 接口中的抽象方法,不需要加abstract修饰 , 方法 默认都是 public abstract
 * 接口中,没有变量,只有常量,并且 public static final 可以省略
 * 
 * 类和接口之间,不再是继承关系,变成了实现关系,extends 换成了 implements
 * 
 * 接口名 变量 = new 子实现类()  也是会发生多态的
 *  
 *  一个类 只能继承一个类,但是 可以实现 N个接口,以逗号隔开,可以解决单继承功能变弱问题
 *  		class 类名 implements 接口1 , 接口2,接口3....{}
 *  
 *  接口和接口之间,是多继承, 多个 已逗号隔开
 *  		interface 接口名 extends 父接口名1,父接口名2,...{}
 *  
 *  一个类 如果实现了一个接口,那么必须实现接口中所有的抽象方法,.否则该类需要加abstract修饰
 *  一个抽象类,实现一个接口,可以实现 0~N个抽象方法
 *  
 *  1.7 只能有抽象方法
 *  1.8 可以有静态方法,也可以有default方法(就理解为成员方法即可)
 *  		静态方法,用接口名调用即可
 *  		default 方法需要同过子实现类调用,同时也可以覆写
 *  1.9 开始 支持 private方法
 *  
 *  如果接口和抽象类都能做到一件事,优先使用接口,因为这样会保留类的继承

4.2 使用方式

interface A{
	
	public static final String name ="xx";
	// psf可以省略
	int age = 2;
	
	public abstract void m1();
	// public和abstract可以省略
	void m2();
	public default void m3(){
		System.out.println("默认方法");
	}
	public static void m4(){
		System.out.println("静态方法");
	}
}
interface B{
	
}
// 多继承
interface C extends B,A{
	
}
// 多实现,需要实现所有的抽象方法
class D implements A,B,C{
	@Override
	public void m1() {
		
	}
	@Override
	public void m2() {
		
	}
}
// 抽象类,可以实现0~N个抽象方法
abstract class E implements A,B,C{
	
}

5. Object

5.1 概述

 * Object 是所有类的祖类,是java中提供的根类
 * 
 * 一个类没有显示继承另一个类的时候,默认继承object
 * 
 * Object xx = new xxx() : 是可以发生多态的

在这里插入图片描述

5.2 Equals

 * == : 比较基本类型的时候,比较值的大小,但是比较引用类型的时候,比较的是内存地址
 * 
 * 而 比较内存地址,是没有任何价值的,我们一般会比较两个对象的属性值,是否一致,而不是比较两个对象地址是否一致
 * 
 * equals() : 该方法设计目的,用来比较两个对象是否相等,但是 默认比较地址
 * 
 * java中Object里面的equals方法,默认比较内存地址(==) 需要我们根据需求进行重写
public boolean equals(Object obj){
	return(this == boj);
}
	// 需求 : 如果两个学生的ID相同 就认为这两个是同一个学生
	// 需求 : 如果两个学生的ID和姓名都相同 就认为这两个是同一个学生
	@Override
	public boolean equals(Object obj) {
		// 判断是不是同一个对象
		if (this == obj) {
			return true;
		}
		// 向下转型
		if (obj instanceof Student) {
			Student s2 = (Student) obj;
			// String类中 覆写了equals方法,比较的是值
			if (this.id == s2.id && this.name.equals(s2.name)) {
				return true;
			}
		}
		return false;
	}
public class Equals_02 {
	public static void main(String[] args) {
		String s1 = new String("xxx");
		String s2 = new String("xxx");
		// false
		System.out.println(s1 == s2);
		// true 因为String中 覆写了 equals方法
		System.out.println(s1.equals(s2));
	}
}

5.3 Finalize

 * finalize : 该方法会在垃圾被回收的时候自动调用,无序程序员手动调用
 * 
 * 垃圾 : 当一个对象,没有更多引用指向它的时候,该对象被视为垃圾数据(就是创建了一个对象,谁也找不到他)
 * 
 * protected void finalize() throws Throwable { }
 * Object中的finalize方法,什么也没有做,需要自己根据需求进行重写
public class Finalize_01 {
	public static void main(String[] args) {
		Person p = new Person();
		// finalize方法没有回收功能,手动调用的话,只是单纯的方法调用而已
		// p.finalize();
		p = null;
		// 程序员可以建议进行垃圾回收
		// System.gc();
		// for (int i = 0; i < 10000000; i++) {
		// new Person();
		// }
	}
}

class Person {
	@Override
	public void finalize() {
		System.out.println(this + "我要被回收了");
	}
}

5.4 toString

 * toString : 代表了当前对象的字符串表示形式
 * 
 * 当我们打印一个引用类型变量的时候,会自动调用该对象的toString方法
 * 
 *Object 中默认的toString方法 是打印该对象的内存地址(hash值)
public class ToString_01 {
	public static void main(String[] args) {
		Person p1 = new Person("张三", 18);
		System.out.println(p1);
		System.out.println(p1.name + ":" + p1.age);
	}
}

class Person {
	public String toString() {
		return this.name + ":" + this.age;
	};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值