一、多态
多态的好处:
1、提高了程序的维护性(由继承保证)
2、提高了程序的扩展性(由多态保证)
代码案例(多态的拓展性)
class Animal{public void eat(){System.out.println("吃");}public void sleep(){System.out.println("睡");}
}class Dog extends Animal{@Overridepublic void eat() {System.out.println("🐕吃🥩");}@Overridepublic void sleep() {System.out.println("🐕侧着睡");}
}class Cat extends Animal{@Overridepublic void eat() {System.out.println("🐱吃🐟");}@Overridepublic void sleep() {System.out.println("🐱蜷着睡");}
}class Sheep extends Animal{@Overridepublic void eat() {System.out.println("🐏吃草");}@Overridepublic void sleep() {System.out.println("🐏趴着睡");}
}class Turtle extends Animal{@Overridepublic void eat() {System.out.println("🐢吃🥩");}@Overridepublic void sleep() {System.out.println("🐢缩着睡");}
}class AnimalTool{public static void useAnimal(Animal animal){animal.eat();animal.sleep();}// public static void useCat(Cat cat){
// cat.eat();
// cat.sleep();
// }
//
// public static void useDog(Dog dog){
// dog.eat();
// dog.sleep();
// }
//
// public static void useSheep(Sheep sheep){
// sheep.eat();
// sheep.sleep();
// }
}public class DuoTaiDemo1 {public static void main(String[] args) {//现在我想养一只🐕Dog d1 = new Dog();
// d1.eat();
// d1.sleep();
// useDog(d1);
// AnimalTool.useDog(d1);AnimalTool.useAnimal(d1);Dog d2 = new Dog();
// d2.eat();
// d2.sleep();
// useDog(d2);
// AnimalTool.useDog(d2);AnimalTool.useAnimal(d2);//我现在不想养🐕,我想养一只🐱Cat c1 = new Cat();
// c1.eat();
// c1.sleep();
// useCat(c1);
// AnimalTool.useCat(c1);AnimalTool.useAnimal(c1);//随着我们养的动物种类越来越多,我们发现//1. 自定义动物的类越来越多【这是不可避免】//2. 当前类中的useXxx的方法越来越多,写在这里其实并不合适,因为这是一个测试类//测试类中主要涉及创建对象调用功能//我们可以将调用动物功能的方法放到一个动物工具类中//我想养一只🐏Sheep s1 = new Sheep();
// AnimalTool.useSheep(s1);AnimalTool.useAnimal(s1);//工具类是不应该频繁被修改的类,也就是说,我们写好一个工具类后,即便我们有新的动物出现,也不需要修改工具类也可以使用//利用多态的扩展性来使用//我想养一只🐢Turtle t1 = new Turtle();AnimalTool.useAnimal(t1);}// public static void useCat(Cat cat){
// cat.eat();
// cat.sleep();
// }
//
// public static void useDog(Dog dog){
// dog.eat();
// dog.sleep();
// }
}
向下转型(当需要用到子类对象自己独有的方法时需要用向下转型)
格式: 子类类名 变量名 = (子类类名)要转型的变量名;
代码案例
class Fu1{public void fun1(){System.out.println("好好学习,天天向上!");}
}class Zi1 extends Fu1{@Overridepublic void fun1() {System.out.println("在数加好好学习,天天向上!");}public void show1(){System.out.println("现在没有睡觉...");}
}class Demo1 extends Fu1{}public class DuoTaiDemo2 {public static void main(String[] args) {Fu1 f1 = new Zi1();f1.fun1();
// f1.show1();//向下转型//格式: 子类类名 变量名 = (子类类名)要转型的变量名;Zi1 z1 = (Zi1)f1;z1.show1();//并不是任意两个类型之间都可以做向下转型,只有实际内存对象类型与要转的类型一样
// Demo1 d1 = (Demo1) f1; //ClassCastException}
}
二、抽象类
java为了表示现实生活中抽象的概念集合,提供了一个关键字给我们使用:abstract
abstract 抽象的
可以修饰类,修饰成员方法1. 被abstract修饰的类是抽象类, 抽象类不能被实例化
2. 被abstract修饰的方法是抽象方法, 抽象方法不能有大括号实现
3. 在抽象类,既可以存在具体实现的方法, 也可以存在抽象方法
4. 若一个类中有抽象方法, 这个类一定是一个抽象类
5. 当一个具体的类继承一个抽象类, 必须要实现抽象类中的所有抽象方法
6. 当一个抽象类继承一个抽象类的时候, 可以选择性地是否重写抽象方法
代码案例
abstract class Animal2{//拥有具体实现的方法public void eat1(){System.out.println("吃饭");}//抽象方法public abstract void eat2();
}abstract class A1 extends Animal2{}class Dog2 extends Animal2{@Overridepublic void eat2() {System.out.println("🐕吃🥩");}
}public class AbstractDemo1 {public static void main(String[] args) {
// Animal2 animal2 = new Animal2();}
}
抽象类与类中成员的关系:成员变量: 抽象类既可以存在变量, 也可以存在常量构造方法: 可以存在构造方法, 是为了将来在继承关系做初始化的作用成员方法: 既可以是具体的实现方法, 也可以是抽象方法
代码案例
abstract class Demo2{
// int a = 10;
// final int b = 20;Demo2(){}
}class A2 extends Demo2{A2(){
// super();}
}public class AbstractDemo2 {public static void main(String[] args) {
// Demo2 demo2 = new Demo2();}
}
- 一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
可以表示一种概念的集合 - abstract不能和哪些关键字共存
final 不能共存
static 不能共存
private 不能共存
代码案例
abstract class ShuJia{
// abstract final void fun1(); // 非法的修饰符组合: abstract和final// abstract static void fun1(); // 非法的修饰符组合: abstract和static// private abstract void fun1(); // 非法的修饰符组合: abstract和private
}public class AbstractDemo3 {public static void main(String[] args) {}
}
三、接口
接口:表示一个类的额外功能的实现
java提供了一个关键字表示接口:interface
接口我们可以将它看作成一个特殊的类, 因为接口也会被编译成一个class文件
接口注意事项:
-
接口中只能存在抽象方法, jvm默认会在方法前使用public abstract进行修饰, 刚学java推荐加上
-
类和接口是实现关系 可以通过关键字implements实现接口
-
当一个具体的类实现一个接口的时候, 必须要实现接口中所有的抽象方法
-
若一个抽象类实现一个接口的时候,可以选择性地实现接口中的抽象方法
-
一个类可以同时实现多个接口,使用逗号隔开
-
接口和接口存在继承关系, 并且一个接口可以同时继承多个接口
-
接口中只能定义常量, 默认修饰符为public static final
-
接口无法实例化, 接口中不能出现构造方法
java中允许多继承吗?答:若是类和类之间的继承,只能单继承,不能多继承若是接口与接口之间的继承,可以多继承
代码案例
interface QiChe{public abstract void qiche();// public void fun1(){
// System.out.println("好好学习");
// }
}abstract class Animal3{public abstract void eat();
}class Bear extends Animal3{@Overridepublic void eat(){System.out.println("🐻吃🥩");}
}class QiCheBear extends Animal3 implements QiChe{@Overridepublic void eat() {System.out.println("🐻吃🥩");}@Overridepublic void qiche() {System.out.println("训练后的🐻会骑车");}
}public class InterfaceDemo1 {public static void main(String[] args) {}
}
interface Inter{void fun1();void fun2();
}interface Inter2 {void fun3();
}interface Inter3 extends Inter,Inter2{//fun1();//fun2();//fun3();void fun4();
}class Demo5 implements Inter,Inter2{@Overridepublic void fun1() {}@Overridepublic void fun2() {}@Overridepublic void fun3() {}
}abstract class Demo4 implements Inter{}class Demo1Impl implements Inter{@Overridepublic void fun1() {}@Overridepublic void fun2() {}
}public class InterfaceDemo2 {public static void main(String[] args) {}
}
interface Inter1{public static final int a = 10;// Inter1(){}
}class Demo6 implements Inter1{public void fun1(){
// a = 20;System.out.println(a);}}public class InterfaceDemo3 {public static void main(String[] args) {
// Demo6 demo6 = new Demo6();
// System.out.println(demo6.a);
// System.out.println(Inter1.a);
// demo6.fun1();// Inter1 inter1 = new Inter1();Inter1 i1 = new Demo6(); // 接口多态}
}