Java多态大乱炖

2024-01-07 04:08
文章标签 java 多态 大乱

本文主要是介绍Java多态大乱炖,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 UML(统一建模语言)类的关系

在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregation),组合(Composition),依赖(Dependency)

① 泛化extends:子类继承父类,一般表示有说 “子类  is  a 父类”

 

② 现实implements,在java中表示实现类和接口的关系

 

③ 关联:是一种拥有的关系,它使一个类知道另一个类的属性和方法。

 

④ 聚合:是整体与部分的关系,且部分可以离开整体而单独存在。

 

⑤ 组合:是整体与部分的关系,且部分不可以离开整体而单独存在。

 

⑥依赖:是一种使用的关系,即一个类的实现需要另一个类的协助,

所以要尽量不使用双向的互相依赖.

二 抽象类和接口

抽象方法:是一种特殊的方法:它只有声明,而没有具体的实现。抽象方法的声明格式为:abstract void fun();

抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。抽象类不能被直接实例化。

抽象类可以不含抽象方法(无意义),也可以有普通方法和静态方法。

如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

2.1抽象类的间接实例化(匿名内部类)

//抽象类
public abstract class One {
//抽象方法 public abstract void ok1(); }

public class Two extends One{
//实现父类全部抽象方法 @Override

public void ok1() { System.out.println("two ok1...."); } }

public class Test {public static void main(String[] args) {// One x=new One(){};
//匿名内部类:相当于又创建了一个类,这个类的父类是One,也要重写抽象父类one的抽象方法,先使用{}创建了类的身体,通过{前面的最
//近的类名告诉编译器我的父类是One,由于使用new关键字在堆中按自定义的{}中语句生成内存;One y=new One(){
//重写public void ok1(){System.out.println("ok1...");}// 父类(one)中没有OK2,不能调用,可以将父类理解为模板public void ok2(){System.out.println("ok2");}};
//        y.ok2();报错
y.ok1();//成功调用        
//多态y=new Two();
//          y.ok2();报错,由于two继承了one,但模板one中没有该方法}
}

多态:instanceof

父类引用指向子类对象:

public class MyNum {public void show(){System.out.println("我是父类的show...");}
}
public class MyOne extends MyNum{public void show() {System.out.println("One show....");}}
public class MyTwo extends MyNum{public void show() {System.out.println("two show....");}public void fly(){System.out.println("飞....");}
}
public class Test {//方法参数的类型是父类,这是多态的主要应用public static void say(MyNum ni){ni.show();调用指向的对象内的方法。前提是父类即模板中有该方法ni.fly();//报错,父类中无该方法。需要转换//判断对象的真实类型  对象引用 instanceof 类型if(ni instanceof MyTwo){//将ni引用的对象,强制类型转换MyTwo t=(MyTwo) ni;t.fly();}}//  public static void say(MyOne ni){ ni.show();}类型不匹配,不被调用public static void main(String[] args) {//引用多态语法MyNum x=new MyTwo();//x的类型是MyNumx.show();x=new MyOne();x.show();say(x);//x按类型匹配,与指向的对象无关。   }
}
(生成setter方法快捷键  alt+insert)

JavaOOP三大特性:封装、继承和多态;

封装:使用类封装自定义属性和方法;包封装多个类等等;

继承:子类继承父类;

多态:一个父类或接口类型的变量,能够存储多个子类或实现类对象引用;

多态作用,提高代码可以重用性;

多态语法:一个变量引用多种对象(有关联关系);

多态用法:主要用于在方法的参数上使用多态语法,提高代码可重用性;

        注意:可以instanceof判断变量的具体类型,通过强制转换;

四 java的interface

java中引入接口弥补java单继承,父子类必须血缘关系特点;现实中多个不同种类的对象在方法上有相似之处,引入抽取相同方法接口(interface)

用法:一个类可以实现一个或多个接口,但是要求必须重写所有抽象方法;

注意: java中类和接口(除了内部类外),访问修饰符只支持public和默认;

//java中接口可以扩展多个接口:public interface IAction extends  Isky,ILand

接口变量默认添加以下三个关键字 public static final 称常量变量。

接口中的抽象方法,默认有public  abstract关键字   

jdk1.8中接口中可以使用default method,可以被调用   public default String nihao ( ){  return "你好!"; }

面试题,抽象类和接口区别?

.语法层面上的区别

  1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

  2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

  4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2.设计层面上的区别

  1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。

  2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

举例:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念,但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?

从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。

4.2 java中关键字

  static, 修饰代码块,变量,方法,内部类;

  final,表示最终不能修改,可以修饰类(该类不能继承)、变量(常量变量)、方法(不能重写,即不能修饰接口中的方法,可以重载)

 面试题:  多态存在的三个必要条件?

  ①要有继承,或实现;②要有重写;③父类引用指向子类对象

5 java中内部类:

1.成员内部类:与类中属性和方法并列内部类;

实例化成员内部类,首先先实例化外部(MTree是外部类,node是内部类)

MTree mt=new MTree()

MTree.Node n=mt.new Node();      //错误的 MTree.Node node=mt.new MTree.Node();

2.静态内部类:静态内部类 static表示当前类的实例化 脱离外部类存在

调用其中的方法也需要new。

3.局部内部类:位于方法或代码块里

4.匿名内部类:

通常用于异步控制上,图形编程,多线程编程;特点,提供抽象类或接口作为模板,然后在方法中的参数指定该抽象类或接口;

当方法执行时,直接在方法中使用匿名内部类

public class Demo03 extends JFrame {

    private JButton btn;

    public Demo03(){

        this.setTitle("我是一个窗口");

        this.setSize(350,300);

        btn=new JButton();

        btn.setSize(100,30);

        btn.setText("你点击我了吗?");

        Container panel = this.getContentPane();

        panel.add(btn);

 

        //向按钮添加点击事件

        btn.addActionListener(new ActionListener() {

            @Override

            public void actionPerformed(ActionEvent e) {

                JOptionPane.showMessageDialog(Demo03.this,"你敢点我!");

            }

        });

    }

    public static void main(String[] args) {

        Demo03 d3=new Demo03();

        d3.setVisible(true);

    }

}

世界上第一位程序员一个妹子,名叫阿达·洛芙莱斯(Ada Lovelace)是英国著名诗人拜伦的女儿。       

这篇关于Java多态大乱炖的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/578669

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2