个人整理非商业用途,欢迎探讨与指正!!
« 上一篇
一个事物的多种形态
在继承关系中,子类重写父类的方法,父类引用子类的对象
满足三个条件从而发生多态
又称为父new子
语法
父类类型 对象 = new 子类类型();
又被称为向上造型,类似于基本类型的自动类型转换
// 向上造型
public static void main(String[] args) {
// 父new子
// 等号左边的类型,当前对象的类型,当前对象的父类类型
Person stu = new Student();
Student stu1 = new Student();
// Object同样可以写到左边
Object stu2 = new Student();
Object input = new Scanner(System.in);
Object str = "helloworld";
}
若发生多态,一点有的方法的重写,父类类型是无法调用子类中独有的方法
编译期类型 = 运行期类型;
编译期:编写代码的时候
"="的左边,等号左边就是写代码时使用的
运行期:在虚拟机上真实运行的
"="的右边
向上造型
父new子,类似于自动类型转换,可以直接使用子类类型为父类引用赋值
向下造型
子new父
若向下造型,必然发生过向上造型
类似于强制类型转换
语法
子类类型 对象 = (子类类型) 父类引用
public static void main(String[] args) {
// 向上造型:为了发生多态
Person stu = new Student();
Person tea = new Teacher();
// 向下造型:调用子类中独有的方法
// 向下之前必有向上
Student s = (Student) stu;
// 向下造型完毕就可以调用子类中独有的方法了
s.study();
Teacher t = (Teacher) tea;
t.teach();
}
向下造型时,可能因为一个父类有多个子类导致向下造型失败,抛出异常ClassCastException
例如:Person tea = new Student();Student stu = (Student) tea;
比较运算符 返回结果为boolean
类型判断关键字,判断对象是否为某个类的类型
语法
对象 instanceOf 类;
作用:可以防止向下造型时类型转换异常的产生
public static void main(String[] args) {
Person stu = new Student();
Person tea = new Teacher();
System.out.println(stu instanceof Student);
System.out.println(stu instanceof Person);
System.out.println(stu instanceof Object);
System.out.println(stu instanceof Teacher);
// 在向下造型时,先判断
if(tea instanceof Teacher) {
Teacher t = (Teacher) tea;
t.teach();
}else {
Student s = (Student) tea;
s.study();
}
}
应用场景:
多态参数:
参数为父类类型,使用子类对象进行赋值,使用起来更加灵活
package com.qf.pojo;
public class DinningHall {
// 方法重载,特殊的多态形式
// 方法重载形成的多态,灵活非常差
// 同学到食堂吃饭
public void eating(Student stu) {
stu.eat();
}
// 老师到食堂吃饭
public void eating(Teacher tea) {
tea.eat();
}
// 阿姨到食堂吃饭
public void eating(Aunt aunt) {
aunt.eat();
}
public void eating(OldMan om) {
om.eat();
}
// 多态参数,更加灵活
public void eating(Person person) {
person.eat();
}
}
//test
public static void main(String[] args) {
// 学生对象
Student stu = new Student();
// 教师对象
Teacher tea = new Teacher();
System.out.println("中午吃饭了...");
// 食堂对象
DinningHall dh = new DinningHall();
// 学生进食堂,学生吃
dh.eating(stu);
// 老师进食堂,老师吃
dh.eating(tea);
// 都去上课了
dh.eating(new Aunt());
// 老人来了
dh.eating(new OldMan());
}
多态返回值:
返回值为父类类型
package com.qf.pojo;
public class Work {
public Person cc(String type){
switch (type) {
case "老师":
return new Teacher();
case "阿姨":
return new Aunt();
case "老人":
return new OldMan();
case "学生":
return new Student();
}
return null;
}
public static void main(String[] args) {
Work work = new Work();
System.out.println(work.cc("老师"));
System.out.println(work.cc("阿姨"));
System.out.println(work.cc("老人"));
System.out.println(work.cc("学生"));
System.out.println(work.cc("服务员"));
}
}
抽象的
动物就是一个抽象的名词,没有动物的直接对象
有一些类,就不该有对象,例如:Animal Person
Aniaml中的eat,sleep等方法/Person中的eat,show等方法,可以有,但是不够具体不够完善
使用abstract修饰一个类,这个不能创建对象,不能使用new,不能被实例化
被abstract修饰的类就是抽象类
抽象类的含义是不够完善的,不够具体的,用于被扩展被继承的
// 抽象类,就是父类,子类的模板,用于被继承,不能创建对象
public abstract class Animal {
}
抽象方法没有方法体
有一些方法不需要方法体,可以使用abstract修饰
抽象方法表示不够具体的,不够完善的,需要被重写的
抽象方法必须存在于抽象类中,没有方法体
子类继承父类时必须重写抽象方法,除非子类也是抽象类
// 抽象类,就是父类,子类的模板,用于被继承,不能创建对象
public abstract class Animal {
// 动物吃的动作 抽象方法必须重写,除非子类也是抽象类
public abstract void eat();
}
// 子类也是抽象的,不用重写抽象方法
// 抽象方法早晚都需要重写
public abstract class Dog extends Animal {
}
// 重写抽象方法
public class Cat extends Animal{
@Override
public void eat() {
// TODO Auto-generated method stub
}
}
抽象类中不一定有抽象方法
有抽象方法的类一定是抽象类
抽象类中必须有构造方法,用于子类创建对象时调用(抽象类不能创建对象,但是必须有构造)
和abstract是相反的,不能和abstract一起使用
表示最终的,不能被继承的,不能被重写的,不能被修改的
修饰的内容:类,方法,变量
不能被继承
常见的最终类:Math,String,System
public final class MyFinal {
}
不能被重写,不可被覆盖
可以在任何类中
public abstract class Animal {
// 最终方法,不能被重写,可以存在于任何类中
public final void dead() {
System.out.println("啊...噶了");
}
}
表示不可改变
public class Cat {
// 只有一次赋值机会
public void eat(final String name) {
// name = "老鼠";
System.out.println("猫吃的东西是:"+name);
}
public static void main(String[] args) {
new Cat().eat("鱼");
new Cat().eat("老鼠");
}
}
往往和public static同时使用,表示静态常量
静态常量:不可以被修改,只能赋值一次,变量名全大写
常见的静态常见为:Math.PI Math.E
// 必须有初始值
public final static int A = 10;
不可以改地址,可以修改final对象的内容
public static void main(String[] args) {
final int[] arr = new int[10];
// final修饰的对象 不能改地址
// arr = new int[20];
// 内容可以修改
arr[0] = 20;
System.out.println(arr[0]);
arr[0] = 30;
System.out.println(arr[0]);
}