JAVA面向对象多态与抽象类
一,Object类
Object类是所有java类的根基
在未声明的父类中,默认继承Object类
public class Animals{
...
}
//默认继承父类等价于
public class Animals extends Object{
...
}
二,toString方法
把对象数据以字符串的形式表示
如果直接调用toString方法,则默认输出对象地址
System.out.println(p.toString());
System.out.println(p2.toString());
System.out.println(p);
System.out.println(p2);
如果需要输出对象数据内容,则需要自己重写toString方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
重写toString方法快捷键(IDEA方法)Alt+Insert–>选择toString()–>OK即可自动生成重写的toString方法
三,equals方法
equals()与==之间的区别
- "=="用来比较基本数据类型时比较其数据值是否相等,比较引用数据类型则比较两者间地址是否匹配
- equals()则只能用来比较引用数据类型的数据是否相等
Object类中定义有:
public boolean equals(Object obj) 方法; 提供定义对象是否“相等”的逻辑。
可以根据需要在用户自定义类型中重写 equals 方法。
快捷键(IDEA方法)Alt+Insert–>选择equals() and hashCode()–>next即可自动生成重写的toString方法
四,Polymorphism多态
4.1 什么是多态
多态是面向对象三大特性之一,指为不同数据类型的实体提供统一的接口
多态具有多种形态即多种表现形式
4.2 如何实现多态
引用变量的两种类型:
编译时类型(模糊一点,一般是一个父类)
由声明时的类型决定。 变量(由变量类型决定)
运行时类型(运行时,具体是哪个子类就是哪个子类)
由实际对应的对象类型决定。通过 动态绑定 调用该对象的方法。 (对象)
public class Polymorphism01 {
public static void main(String[] args) {
//标准正常形态:对应类型的引用指向对应类型的数据
Person p = new Person();
Student s = new Student();
//多态
//父类引用指向子类对象
Person person = new Student();
//多态调用
System.out.println(person.name);
person.sleep();
}
}
class Animal{}
class Person{
String name= "Person";
void sleep(){
System.out.println("闭着眼睛睡觉!!!");
}
}
class Student extends Person{
String name= "Student";
void sleep(){
System.out.println("边上课边睡觉!!!");
}
}
4.3 多态的使用要点
多态是方法的多态,属性没有多态性
多态的存在要有3个必要条件:
- 要有继承
- 要有方法重写
- 父类引用指向子类对象
五,对象的转型
与数据类型转换差不多,都分为自动类型提升和强制类型转换
向上转型: 小->大
Fu f = new Zi();
向下转型: 大->小
Zi z = (Zi)f;
public class CastTest {
public static void main(String[] args) {
//自动类型提升,子类自动提升为父类
Fu f1 = new Fu();
Fu f2 = new Zi();
Fu f3 = new Zi2();
Fu f4 = new Sun();
System.out.println("-------------------------");
//强制类型转换,父类强制转换为子类
Zi z1 = (Zi)new Fu();//父类直接强转为子类会出现ClassCastException异常报错
Fu f = new Zi();//"伪"父类能间接转换为子类
Zi z2 = (Zi)f;//即子类伪装成父类,但其本质终究是子类
Zi z3 = new Zi2();//两个共同父类的子类之间无法直接转换,可以间接转换,但会有时会出现逻辑不通的问题
}
}
//父类
class Fu{
String name;
int age;
void test(){
System.out.println("Fu类方法");
}
}
//继承Fu父类的子类1
class Zi extends Fu{
@Override
void test() {
System.out.println("Zi类方法");
}
}
//继承Fu父类的子类2
class Zi2 extends Fu{
@Override
void test() {
System.out.println("Zi2类方法");
}
}
//继承Zi父类的子类
class Sun extends Zi{
@Override
void test() {
System.out.println("Sun类方法");
}
}
instanceof 运算符–>避免遇到类型转换异常
引用 instanceof 类型 : 判断前面的引用是否是指向后面类型的对象|子类对象->是true | 不是false
//即对象xxx是否是类xxx的实例
System.out.println(z2 instanceof Fu);//true
System.out.println(z2 instanceof Zi);//true
System.out.println(z2 instanceof Sun);//false
System.out.println(f instanceof Zi);//true
System.out.println(f instanceof Zi2);//false
六,抽象类与抽象方法
6.1 抽象类
即模板类,抽象类为所有子类提供了一个通用模版,子类可以在这个模版基础上进行扩展
通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
6.2 抽象方法
不需要方法体的方法,需要用 abstract 关键字修饰。只能出现在抽象类中。
6.3 抽象类的使用要点
- 有抽象方法的类只能定义能抽象类
- 抽象类不能实例化,即不能用new来实例化抽象类。
- 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
- 抽象类只能用来继承。
- 抽象方法必须被子类实现。
6.4 抽象类与抽象方法的定义
抽象类: 被abstract修饰的类
抽象方法: 被abstract修饰的方法
没有方法体
要求定义在抽象类中
//定义抽象类Animals
abstract class Animals{
//定义抽象方法call
abstract void call();//抽象方法没有方法体,即没有{}
}
6.5 抽象类的使用
通过具体子类的对象使用
public class AbstractDemo {
public static void main(String[] args) {
Wolf wo = new Wolf();
wo.call();
Wolf dog = new Dogs();
dog.call();
}
}
//定义抽象类Animals
abstract class Animals{
//定义抽象方法call
abstract void call();
}
//具体的子类
class Wolf extends Animals{
//重写父类抽象方法
void call(){
System.out.println("嗷嗷叫");
}
}
//继承具体的子类,不用重写抽象方法,直接继承具体子类的重写方法
class Dogs extends Wolf{
void call(){
System.out.println("汪汪叫");
}
}