3.4 多态
【Java初级学习笔记|Java语法之多态、抽象类、引用型的数据类型转换、Object类的使用】多态 : 一种事物的多种形态|表现形式,是一种行为多态。
- 多态前提 :
- 继承 | 实现
- 多态的最终表现形式 :
- 父类引用指向子类对象
- 多态的调用 : 父类引用调用
- 成员变量 :编译运行看父类|左边|类型
- 成员方法 :编译看父类|左边|类型,运行找子类|右边|对象
- 注意:
- 如果没有配合方法的重写,多态就没有意义。方法没有重写的话,就可以直接用对象直接调用不同名的方法。
public class Class001_Poly {
public static void main(String[] args) {
//对应类型数据赋值给对应类型的变量
Person p = new Person();
Student s = new Student();
//正常调用 : p或者s调用的成员 : 1)自己类中存在的成员2)从父类中继承的成员//多态
Personps=new Teacher();
//多态的调用
System.out.println(ps.str);
ps.test();
}
}class Person{
String str = "父类";
public void test(){
System.out.println("Person----> test");
}
}class Student extends Person{
String str = "子类";
public void test(){
System.out.println("Student----> test");
}
}class Teacher extends Person{
String str = "子类2";
public void test(){
System.out.println("Teacher----> test");
}
}
3.4.1 数据类型转换
- 基本 : 数据类型转换
- 自动类型提升 : 小 —> 大
- 强制类型转换 : 大 —> 小
- 小范围类型 变量 = (小范围类型)大范围类型数据;
- 引用 : 转型
- 小: 子类 大 : 父类
- 向上转型 : 子类 --> 父类
- 向下转型 : 父类 --> 子类
- 子类类型 变量 = (子类类型)父类引用;
- 需求 : 当多态调用不能调用子类独有内容时候,可以向下转型,然后调用子类独有内容
- java.lang.ClassCastException类型转换异常
- 在向下转型的时候,如果抓成其他的子类类型,就会遇到这个异常
- instanceof 运算符
- 引用 instanceof 类型 : 判断前面的引用是否指向后面类型的对象或者后面类型的子类对象,如果是返回true,不是返回fales
public class Class001_Cast {
public static void main(String[] args) {
int i = 1;
//自动类型提升
long l = i;
//强制类型转换
int i2 = (int)l;
Zi zi = new Zi();
//向上转型
Fu fu = zi;
//多态
Fu f = new Zi();
//f对子类新增内容不可见//向下转型
//Zi zi2 = (Zi)f;
//Zi zi2 = new Zi();
--> 可以调用子类独有内容
//转型转错了,转成了其他的子类类型---> java.lang.ClassCastException类型转换异常if(f instanceof Brother){
Brother zi2 = (Brother)f;
//Brother zi2 = new Zi();
--> 可以调用子类独有内容
zi2.test();
}else if(f instanceof Zi){
Zi zi2 = (Zi)f;
zi2.test();
}System.out.println(f instanceof Fu);
//T
System.out.println(f instanceof Zi);
//T
System.out.println(f instanceof Brother);
//F
}
}
class Fu{}class Zi extends Fu{
String str="Zi";
void test(){
System.out.println("子类Zi方法test");
}
}class Brother extends Fu{
String str="Brother";
void test(){
System.out.println("子类Brother方法test");
}
}
3.4.2 Object类
- Object : 老祖宗类
- 是java中所有类的父类
- 如果一个类没有显示的继承父类,默认继承自Object类
- toString :返回对象的字符串表现形式
- public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
当输出一个对象 的引用的时候,输出的是对象的引用调用toString方法的返回值==>默认调用toString - 为什么要在子类中重写toString方法 :
- 因为输出对应的引用时候不想是打印对象的地址值,想要输出对象的所有属性值,对从Object中继承的toString需要,toString实现不满意,在子类中重写toString
- 注意:当定义javabean类型,规范都需要重写toString
- public String toString() {
-
==
:比较两个数据是否相等
- 基本 : 数据值
- 引用 : 对象地址值
-
equals
:比较两个对象数据是否相等
- Object类中的equals方法 : 默认比较对象的地址值
public boolean equals(Object obj) {
return (this == obj);
}
- Object类中的equals方法 : 默认比较对象的地址值
- 为什么要子类中重写equals方法 :
- 使用Object类的equals方法,默认比较对象地址,业务需求想要比较根据对象的属性值比较是否相等,可以在子类中根据需要重写equals,实现比较对象所有属性而非地址值
- 注意:javabean的定义规范 :
- 类是公共的
- 至少提供一个空构造
- 属性私有化
- 公共的访问方式
- 重写equals与toString方法
public class Class001_Object{
public static void main(String[] args) {
Student s1 = new Student(1001,"张三丰",100);
Student s2 = new Student(1001,"张三丰",10);
System.out.println(s1);
System.out.println(s1.toString());
System.out.println(s1.equals(""));
;
}
}classStudent{
int no;
String name;
int age;
public Student(){}
public Student(int no,String name,int age){
this.no = no;
this.name = name;
this.age = age;
}public String toString() {
return no+"-->"+name+"-->"+age;
}//比较字符串类型的数据 : 使用String重写的equals比较字符串对象的内容而非地址
public boolean equals(Object obj) { //Object obj = new Student(1001,"张三丰",100);
//增强程序健壮性判断
if(this==obj){
return true;
}
//两个对象 : thisobj
//obj向下转型
if(obj instanceof Student){
Student s = (Student)obj;
//两个对象 : thiss
return this.no==s.no && this.age==s.age && this.name.equals(s.name);
}
return false;
}
}
3.4.3 抽象类
- 抽象类 : 被abstract修饰的类
- 抽象方法 :被abstract修饰的方法
- 没有方法体
- 必须存在与抽象类中
- 需求 :定义开发部门不同职位工作内容
- 开发部门 Develop --> work()
- java攻城狮 : work–> 后端开发
- web程序猿 : work–> 前端开发
- 注意 :
- 抽象类不能实例化
- 抽象方法必须存在与抽象类中
- 抽象类中可以定义可以不定义抽象方法,可以定义任意内容
- 抽象类的使用 :
- 具体子类对象调用成员
重写所有的抽象方法 + 按需新增 - 抽象子类
按需重写 + 按需新增
- 具体子类对象调用成员
- 抽象方法必须被重写的,但是只需要重写一次,按需重写多次
- abstract不能与private,final,static,native一起使用
public class Class001_Abstract {
public static void main(String[] args) {
//抽象类不能实例化
//Develop d = new Develop();
//具体子类对象
Java java = new Java();
java.sleep();
java.work();
java.test();
java.insert();
}
}//父类
abstract class Develop{
//work方法体不知道怎么写,不知道写什么--->
public abstract void work();
public abstract void sleep();
public void test(){
System.out.println("抽象方法的test");
}
}//具体子类
class Java extends Develop{@Override
public void work() {
System.out.println("后端开发");
}@Override
public void sleep() {
System.out.println("边敲代码边睡觉... ");
}//新增
public void insert(){
System.out.println("java中新增方法");
}
}//抽象子类
abstract class Web extends Develop{@Override
public void work() {
System.out.println("前端开发");
}//新增
public void webInsert(){
System.out.println("web 新增");
}
}
推荐阅读
- Java初级学习笔记|Java语法之多线程(线程的创建,线程的状态,线程安全)的使用
- Spring|Ribbon负载均衡(源码解析)
- 面试|中高级测试工程师面试题(不断补充中)
- 微服务大行其道的今天,Service Mesh是怎样一种存在()
- Qt入门|Qt QProgressBar详解
- [Ljava.lang.Object;是什么?
- Kotlin Class 自定义类
- spring|阿里巴巴内部纯享的这份SpringBoot+VUE全栈开发实战手册,绝了
- kubernetes|你不是不会处理多行日志,只是不会写正则表达式而已~