java_day8_多态、抽象类、接口
一、多态
多态的好处:
1、提高了程序的维护性(由继承保证)
2、提高了程序的扩展性(由多态保证)
代码案例(多态的拓展性)
class Animal{
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("🐕吃🥩");
}
@Override
public void sleep() {
System.out.println("🐕侧着睡");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("🐱吃🐟");
}
@Override
public void sleep() {
System.out.println("🐱蜷着睡");
}
}
class Sheep extends Animal{
@Override
public void eat() {
System.out.println("🐏吃草");
}
@Override
public void sleep() {
System.out.println("🐏趴着睡");
}
}
class Turtle extends Animal{
@Override
public void eat() {
System.out.println("🐢吃🥩");
}
@Override
public 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{
@Override
public 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{
@Override
public 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{
@Override
public void eat(){
System.out.println("🐻吃🥩");
}
}
class QiCheBear extends Animal3 implements QiChe{
@Override
public void eat() {
System.out.println("🐻吃🥩");
}
@Override
public 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{
@Override
public void fun1() {
}
@Override
public void fun2() {
}
@Override
public void fun3() {
}
}
abstract class Demo4 implements Inter{
}
class Demo1Impl implements Inter{
@Override
public void fun1() {
}
@Override
public 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(); // 接口多态
}
}
分类:
大数据学习之路 / Java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现