本文主要是介绍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多态大乱炖的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!