Day08 学习java(多态,abstract,intrtface)

1.final

1.1是什么

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

1.2能做什么

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

1.3怎么用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常量名建议全部大写

final static public int ID = 1;

1.4修饰引用类型

//先给出一个Customer类
class Customer {
	String name;
	int age;

	public Customer(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

在这里插入图片描述

2.多态

2.1是什么

父类引用指向子类对象
父类引用:用父类声明的引用类型变量
指向:通过内存地址可以找到哪个对象
子类对象: new 子类创建的堆内存对象

2.2相关知识

软件设计六大原则:

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

2.3优点

优点:同一操作,作用于不同对象,可以有不同的解释,产生不同的结果,这就是多态性。当一件事会有很多种不同实现方式的时候,我们选择依赖高层来拥抱多种变化,本质还是降低类和细节之间的耦合度

2.4缺点

缺点:丢失子类特有的属性

2.5使用语法

public class Poly_01 {

	public static void main(String[] args) {

		// 多态
		Animal a = new Cat();
		a.eat();
		a = new Dog();
		a.eat();
	}

}

class Animal {
	public void eat() {
		System.out.println("动物吃东西");
	}
}

class Cat extends Animal {
	public void eat() {
		System.out.println("猫吃鱼");
	}
}

class Dog extends Animal {
	public void eat() {
		System.out.println("狗吃肉");
	}
}

2.6多态的几种形式

public class Poly_02 {

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

	}

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

	public static void m1(Sup sup) {

	}
}

class Sup {

}

class Sub extends Sup {

}

2.7多态进行属性调用

多态进行属性调用:
1.如果父类没有直接报错,不管子类有没有
2.如果父类有,子类没有,直接执行父类
3.父类和子类都有,成员方法执行子类,因为成员方法可以覆写,其他的都执行父类
4.多态又叫向上转型

public class Poly_03 {

	public static void main(String[] args) {
		// 多态
		SupClass sup = new SubClass();
		// 父类和子类都有的成员方法,执行子类
		sup.m2();
		// 父类没有子类有,报错
		// sup.m3();
		// 父类和子类都有的静态方法,执行父类
		sup.m1();
		// 成员变量也是父类
		System.out.println(sup.i);

		// 此时,由于多态原因,子类特有属性访问不到,想要访问也行,但是要先向下转型
		// 必须先发生向上转型,才能发生向下转型
		SubClass sub = (SubClass) sup;
		sub.m3();
		// 没有发生向上转型的话,如果使用向下转型会报错,类型转换异常
		SupClass sup1 = new SupClass();
		// SubClass sub1 = (SubClass) sup1;
		// instanceof:判断某个对象是否由某个类实例化而来
		if (sup1 instanceof SubClass) {
			// 如果是,就向下转型,不是就不转,可以避免类型转换异常
			SubClass sub1 = (SubClass) sup1;
		}
	}

}

class SupClass {
	int i = 1;

	public static void m1() {
		System.out.println("父类静态方法m1");
	}

	public void m2() {
		System.out.println("父类成员方法m2");
	}

}

class SubClass extends SupClass {
	int i = 2;

	public static void m1() {
		System.out.println("子类静态方法m1");
	}

	public void m2() {
		System.out.println("子类成员方法m2");
	}

	public void m3() {
		System.out.println("子类独有的成员方法m3");
	}
}

在这里插入图片描述

2.7instanceof

判断某个对象是否由某个类实例化而来
在这里插入图片描述

3.abstract

3.1是什么

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

3.2使用语法

abstract class Animal {
	// 吃饭的功能
	abstract public void eat();
	public void m1() {
		System.out.println(this+"Animal 的m1方法");
	}
}

class Cat extends Animal {
	@Override
	public void eat() {
		System.out.println("猫吃鱼");
	}
}

4.interface

4.1是什么

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

4.2使用方式

语法:修饰符 interface 接口名 {}

public class interface_01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}

interface A {
	public static final String name = "xxx";
	int age = 18;

	public abstract void m1();

	void m2();

	public default void m3() {
		System.out.println("默认方法");
	}

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

interface B {

}

interface C extends A, B {

}

class D implements A, B, C {

	@Override
	public void m1() {

	}

	@Override
	public void m2() {

	}

}

abstract class E implements A, B, C {

}

5.object

5.1概述

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

5.2equals

==:比较基本类型的时候,比较值的大小,但是比较引用类型的时候,比较的是内存地址
而比较内存地址是没有任何价值的,我们一般会比较两个对象的属性值是否一致,而不是比较两个对象的地址是否一致

equals():该方法设计目的,用来比较两个对象是否相等,但是默认比较地址

java中Object里面的equals方法,默认比较内存地址,需要我们根据需求进行重写

public class Equals_01 {

	public static void main(String[] args) {
		Student s1 = new Student(2018, "张三");
		Student s2 = new Student(2018, "张三");
		System.out.println(s1 == s2);
		System.out.println(s1.equals(s2));
	}

}

class Student {
	int id;
	String name;

	public Student(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	// 需求: 如果两个学生的ID相同 就认为这两个是同一个学生
	// 需求 : 如果两个学生的ID和姓名都相同 就认为这两个是同一个学生

	@Override
	public boolean equals(Object obj) {
		// 判断是不是同一个对象
		if (this == obj) {
			return true;
		}
		// 向下转型,因为此时传进来的参数用不到子类的特有属性
		if (obj instanceof Student) {
			// if(this.id==obj.id;){
			// }
			// 向下转型
			Student s2 = (Student) obj;
			// String类中覆写了equals方法,比较的是值
			if (this.id == s2.id && this.name.equals(s2.name))
				return true;
		}
		return false;
	}

}

在这里插入图片描述

5.3 finalize

该方法会在垃圾被回收的时候自动调用,无程序员手动调用
垃圾:当一个对象没有更多引用指向它的时候,该对象被视为垃圾数据(就是创建了一个对象,谁也找不到他)finalize方法没有回收功能,手动调用的话,只是单纯的方法调用而已

public class Finalize_01 {

	public static void main(String[] args) {
		Person p = new Person();
		p=null;
		// finalize方法没有回收功能,手动调用的话,只是单纯的方法调用而已
		// 程序员可以建议进行垃圾回收,但是回收不回收就是另一回事了
		System.gc();
	}

}

class Person {

	@Override
	protected void finalize() throws Throwable {
		System.out.println(this + "我要被回收了");

	}

}

5.4toString

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 {
	String name;
	int age;

	@Override
	public String toString() {
		return "我是" + this.name + ":" + this.age;
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 抽象类是Java中的一种特殊类型的类,不能被实例化,只能被其他类继承并实现其抽象方法。抽象类中可以有非抽象方法,但必须至少有一个抽象方法。抽象类常常作为一个如果要实现某些方法,必须先要实现某些其他方法的类,或者是一个共同特征较多的类的共同抽象。通过继承抽象类,子类可以获得抽象类中定义的变量和方法,同时必须实现所有的抽象方法,才能被实例化。 ### 回答2: Java语言中的继承和多态是其面向对象编程的核心内容之一。而抽象类是继承和多态的重要手段。抽象类是一种不能被实例化的类,它存在的主要目的是为了被子类继承。 抽象类的主要特征是:包含抽象方法和非抽象方法。抽象方法必须要被子类实现,而非抽象方法可以在抽象类中有默认的实现。抽象类的定义方式是在类名前加上abstract关键字,例如: abstract class Animal { ... public abstract void makeSound(); ... } 在这个例子中,Animal类是一个抽象类,其中包含了一个抽象方法makeSound()。子类继承Animal类时,需要实现makeSound()方法。抽象类的主要作用是为继承层次结构中的相关类提供一个通用的父类,同时限制抽象类的实例化,使得子类必须实现抽象方法。 抽象类的另一个重要用途是实现多态性。多态性是指同一个方法名在不同的对象中的行为不同。通过抽象类的多态性,我们可以实现类似于“鸟类可以飞”的描述,这就是面向对象编程中的多态性。 总之,抽象类是Java语言的一个重要机制,它的通过继承和多态性实现类的层次结构和通用化,同时限制抽象类的实例化,强制子类必须实现继承结构中通用的抽象方法。在Java程序设计中,了解和掌握抽象类的用法和特点是非常重要的。 ### 回答3: 在Java中,abstract类是一种特殊的类,它不能被实例化,只能被用作其他类的父类或者作为抽象方法的容器。一般情况下,abstract类用于将某些通用行为封装到一个顶级类中,以便它们可以在多个派生类之间共享。同时,abstract类还可以用来定义抽象方法,这些方法没有具体实现,只是提供了一种约定,即任何派生类都必须实现这些方法。 Java继承机制允许派生类继承父类的属性和方法,同时可以重写这些方法和添加新的方法。而多态则是指同一类型的实例对象在不同的上下文环境下表现出不同的行为。Java中的abstract类和多态机制结合使用,可以让程序员更加方便地创建可扩展的应用程序。 通过继承一个abstract类,派生类可以继承abstract类中定义的方法和变量,并在派生类中重写这些方法以实现派生类的独特功能。同时,派生类也可以通过实现抽象方法来实现多态。例如,在一个程序中,有一个Shape类,它是一个abstract类,其中包含一个抽象方法area(),用于计算图形的面积。由于面积的计算方式在不同的图形中是不一样的,因此派生类需要实现这个抽象方法来满足具体的需求。 在Java中,abstract类和接口是实现多态的两种主要方式。abstract类通常用于表示一类具有共同特性的对象,而接口则强调对象之间的方法调用和行为规范。无论是abstract类还是接口,它们都可以被用作多态的基础,允许程序员通过简单的代码实现复杂的功能。 总之,abstract类是面向对象编程中重要的一环,它是Java中实现继承和多态的重要手段。通过继承一个abstract类,并实现其中的抽象方法,Java程序员可以更加方便地开发出可扩展的应用程序。同时,abstract类和多态机制的结合使用,也为程序员提供了更大的创作空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值