目录
①抽象类中可以定义成员变量,成员变量私有修饰,提供方法 get/set,由子类的对象使用
③抽象类中,可以不定义出抽象方法,但是,如果有抽象方法存在,这个类必须是抽象类
静态内存优先于对象,在静态的方法中不能使用this和super
面向对象多态
一、对象的多态性
一个事物具备不同的形态
1.对象多态性前提
必须有继承或是接口实现
必须有方法的重写
语法规则:
父类或者接口的引用指向自己的子类的对象
多态写法:
父类 变量(对象名) = new 子类对象();
对象调用方法,执行的子类的方法重写
例:
父类:System.out.println("人在吃饭");
子类:System.out.println("学生在吃饭");
public static void main(String[] args){
//多态性,创建对象
//父类或者接口的引用指向自己的子类的对象
Person p = new Student();
//对象调用方法
p.eat();
}
结果:学生在吃饭
2.多态中成员的特点
①多态中成员变量的特点
编译 : 父类中没有成员变量,编译失败
运行 : 运行父类中的成员变量
②多态中成员方法的特点
编译 : 父类中没有成员方法,编译失败
运行 : 运行子类的方法重写
public class Person {
String s = "父类成员";
public void eat(){
System.out.println("人在吃饭");
}
}
public class Student {
String s = "子类成员";
public void eat(){
System.out.println("学生在吃饭");
}
}
Person p = new Student();
简练 : 成员方法编译看左边,运行看右边.成员变量都是左边
3.多态的转型
多态的程序中,不能调用子类的特有成员,只能调用子类父类的共有成员。
公式:
转后类型 变量名 = (转后类型)要转的数据;
public static void main(String[] args) {
//创建对象,多态性
//父类 = new 任意子类对象() 扩展
Animal animal = new Cat();
animal.eat();
//Cat类的特有功能 catchMouse()方法
//类型转换,强制
//Cat提升为了Animal,转回Cat类型
Cat c = (Cat)animal;
c.catchMouse();
}
类型提升
4.多态中的异常转型
异常ClassCastException 类型转换异常,在多态中经常发生
运算符 :
比较运算符,结果是boolean类型
运算符是关键字 instanceof
instanceof的语法格式:
对象名 instanceof 类的名字
比较这个对象,是不是由这个类产生的
例:c instanceof Cat c对象是不是Cat类产生的,如果是结果就是true
public static void main(String[] args) {
//多态创建对象
Animal animal = new Dog();
animal.eat();
//判断 animal是不是Cat类的对象
//boolean b = animal instanceof Dog ;
//System.out.println(b);
//调用子类的特有方法
if (animal instanceof Cat){
//if为true,强制转换为Cat
Cat c = (Cat)animal;
c.catchMouse();
}
if (animal instanceof Dog){
Dog d = (Dog)animal;
d.lookHome();
}
}
5.多态的转型案例
public static void main(String[] args) {
//创建对象,多态
Person p1 = new Faculty();
//p1对象的属性,赋值本科 degree 子类的特有成员
//判断p1对象是不是Faculty类产生
if (p1 instanceof Faculty){
Faculty f = (Faculty)p1;
f.setDegree("本科");
System.out.println(f.getDegree());
}
Person p2 = new Staff();
//判断p2对象是不是Staff类产生
if (p2 instanceof Staff){
Staff s = (Staff)p2;
s.setDuty("职员");
System.out.println( s.getDuty());
}
}
二、抽象类 abstract
程序中 : 我知道这个功能存在,但是怎么完成就说不清楚,程序中也出现了抽象.
1.抽象方法定义
使用关键字 abstract定义抽象方法
权限修饰符 abstract 返回值类型 方法名字(参数列表) ;
注意:
抽象方法没有方法体, 不需要{},直接分号结束
当一个类中的方法是抽象方法的时候,这个类必须是抽象类,在类的关键字class前面使用abstract修饰.
例:
public abstract class Animal {
/**
* 动物吃什么?
* 说不清楚,抽象,可以不说
*/
public abstract void eat();
}
2.抽象类的使用方法
注意:
Ⅰ抽象类不能实例化对象,不能new对象
Ⅱ类中有没有主体的方法存在,建立对象调用抽象方法是绝对的错误,因此不能建立对象
Ⅲ需要子类继承抽象类,重写抽象方法
创建子类对象:
使用多态性创建对象,调用方法执行子类的重写
例:
public class Cat extends Animal{
/**
* 重写父类的方法
* 去掉修饰符 abstract
* 添加主体 {}
*/
public void eat(){
System.out.println("猫吃鱼");
}
}
public static void main(String[] args) {
//创建Animal的子类对象
Animal animal = new Cat();
//eat方法不可能执行父类,运行子类的重写
animal.eat();
}
3.抽象中成员的定义
①抽象类中可以定义成员变量,成员变量私有修饰,提供方法 get/set,由子类的对象使用
②抽象类中有构造方法,不写有默认的
③抽象类中,可以不定义出抽象方法,但是,如果有抽象方法存在,这个类必须是抽象类
4.子类还是抽象类的问题
当一个子类继承一个抽象类的时候,子类必须重写全部的抽象方法.假如子类重写了部分抽象方法,这个子类依然还是抽象类
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
public abstract class Cat extends Animal {
public void eat(){}
/**
* 方法sleep没有重写
* 还是一个抽象的方法
*/
// public abstract void sleep();
}
只重写了一个方法,sieep没有重写,还是一个抽象的方法
5.员工案例
父类:
/**
* 公司类
* 定义的是所有员工的共性内容
*/
public abstract class Company {
private String name; //员工姓名
private String id; // 员工编号,唯一标识
//工作行为,具体到某个岗位是不同,无法写出具体的工作内容
public abstract void work();
public String getName() {
retu