- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java基础的详细了解第八天由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
多态性是面向对象的最后一个特征,它本身主要分为两个方面:
方法的多态性:重载与覆写 。
1、重载:同一个方法名称,根据参数类型以及个数完成不同功能; 。
2、覆写:通一个方法,根据操作的子类不同,所完成的功能也不同.
对象的多态性:父子类对象的转换.
1、向上转型:子类对象变为父类对象,父类 父类对象 = 子类 子类对象 自动; 。
2、向上转型:父类对象变为子类对象,格式:子类 子类对象 = (子类)父类实例,强制; 。
class A{ public void print(){ System.out.println("A输出"); }}class B extends A{ public void print(){ System.out.println("B输出"); }}public class TestDemo1{ public static void main(String args[]){ B b = new B(); //B输出 b.print(); }}
这种操作主要观察两点:
1、 看实例化的是哪一类(new); 。
2 、看new的这个类之中是否被覆写了父类调用的方法.
。
public class TestDemo1{ public static void main(String args[]){ A a = new B(); //向上转型 //B输出 a.print(); }}
。
public class TestDemo1{ public static void main(String args[]){ A a = new B(); //向上转型 B b = (B) a; //向下转型 b.print(); }}
public class TestDemo1{ public static void main(String args[]){ A a = new A(); //没有转型 B b = (B) a; //向下转型 b.print(); }}/*Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B at DuoTaiXing.main(TestDemo1.java:14)*/
以上的程序在编译的时候没有发生任何错误信息,但是在执行的时候出现了“ClassCastException”错误提示,表示的是类转换异常,即:两个没有关系的类互相发生了对象的强制转型.
转型的因素:
class A{ public void print(){ System.out.println("A输出"); }}class B extends A{ public void print(){ System.out.println("B输出"); } public void funB(){ System.out.println("funB"); }}public class TestDemo1{ public static void main(String args[]){ A a = new B(); //向上转型 System.out.println(a instanceof A); System.out.println(a instanceof B); if (a instanceof B){ B b = (B) a; b.funB(); } }}/*truetruefunB*/
为了日后的操作方便,在编写代码的时候,尽量不要去执行向下的转型操作,子类尽量不要去扩充新的方法名称(父类没有的方法名称),依据父类定义的操作完善方法.
例题:利用对象向上转型完成 。
class A{ public void print(){ System.out.println("A输出"); }}class B extends A{ public void print(){ System.out.println("B输出"); }}class C extends A{ public void print(){ System.out.println("C输出"); }}public class TestDemo2{ public static void main(String args[]){ fun(new B()); fun(new C()); } public static void fun(A a){ a.print(); }}
这样以来就得到了类型的统一,就算有再多的子类出现,方法或者是类也不需要进行修改了,但是在这块必须强调的是:子类操作的过程之中,尽量向父类靠拢.
以后所有的代码之中,都会存在对象的转型问题,并且向上转型居多.
在日后的所有开发之中,像之前程序那样,一个类去继承另外一个已经实现好的类的情况,是不可能出现的。即:一个类不能去继承一个已经实现好的类,只能继承抽象类或实现接口.
。
在以后你进行的项目开发中,绝对不要出现一个类继承一个已经实现好的类.
对象多态性的核心本质在于方法的覆写,这样的操作有些不合要求,所以要对子类的方法进行强制的要求就必须采用我们的抽象类进行实现.
。
普通类就是一个完善的功能类,可以直接产生对象并且可以使用,里面的方法都是带有方法体的,而抽象类之中最大的特点是包含了抽象方法,而抽象方法是只声明而未实现(没有方法体)的方法,而抽象方法定义的时候要使用abstract关键字完成,而抽象方法一定要在抽象类之中,抽象类要使用是用abstract声明.
abstract class A{ private String msg = "www.baidu.com";//属性 public void print(){ //普通方法 System.out.println(msg); } //{}为方法体,所有的抽象方法上是不包含有方法体的 public abstract void fun() ; //抽象方法}public class ChouXiang{ public static void main(String args[]){ /* ChouXiang.java:12: 错误: A是抽象的; 无法实例化 A a =new A(); ^ 1 个错误 */ A a =new A(); }}
抽象类比普通类多了抽象方法而已,没有上面特殊的.
。
抽象类中包含抽象方法,而抽象方法与普通方法最大的区别就是没有方法体,不知道具体的实现,而如果产生了实例化就意味着以可以调用类中的所有操作.
抽象类的使用原则:
abstract class A{ private String msg = "www.baidu.com";//属性 public void print(){ //普通方法 System.out.println(msg); } //{}为方法体,所有的抽象方法上是不包含有方法体的 public abstract void fun() ; //抽象方法}//一个子类只能够利用extends来继续继承抽象类,所以依然存在单继承局限 class B extends A{//定义抽象类的子类 public void fun(){ System.out.println("Hello"); }}public class ChouXiang{ public static void main(String args[]){ A a =new B();//向上转型 a.print(); a.fun(); }}
通过以上的一个程序,现在就可以清楚的发现,与之前类不一样的是,抽象类定义出了子类必须要覆写的方法,而之前的类子类可以有选择性的来决定是否覆写。而且可以发现,抽象类实际上就比普通类多了一些抽象方法而已,其他的定义和普通类完全一样。如果把普通类比喻成一盘炒熟的菜,那么抽象类就是一盘半成品.
。
1、抽象类能否使用final定义?
不能,因为final定义的类不能有子类,而抽象类必须有子类.
2、抽象类之中能否包含构造方法?
可以,因为抽象类之中除了包含抽象方法之外,还包含了普通方法和属性,而属性一定要在构造方法执行完毕之后才可以进行初始化操作; 。
3、抽象类之中能否不包含抽象方法?
可以,抽象类之中可以没有抽象方法,但是反过来来讲,如果有抽象,则一定是抽象类。即使抽象类之中没有抽象方法也不能被直接实例化.
4、抽象类能否使用static声明?
如过定义的是外部抽象类,则不能够使用static声明,可是如果定义的是内部类,那么这个内部的抽象类使用了static声明之后,就表示一个外部的抽象类.
abstract class A{ private String str = "Hello,China"; static abstract class B{ public abstract void print(); } }class C extends A.B{ public void print(){ System.out.println("你好,中国"); }}public class ChouXiang{ public static void main(String args[]){ A a =new B();//向上转型 a.print(); }}
结论:如果构造方法没有执行,类中对象中属性一定都是其对应数据类型的默认值.
抽象类的最大特点在于强制规定了子类的实现结构.
。
抽象类和普通类最大的特点就是约定了子类的实现要求:但是抽象类有一个缺点――单继承局限,如果要想要求以及避免单继承局限,就需要使用接口。在以后的开发中,接口优先,在一个操作中既可以使用抽象类又可以使用我们的接口,优先考虑接口.
。
接口就是一个抽象方法和全局常量的集合,属于一种特殊的类,如果一个类定义的时候全部由抽象方法和全局常量所组成的话,那么这种类就称为接口,但是接口是使用interface关键字定义的.
interface A{//定义接口 public static final String INFO="Hello,World"; public abstract void print();}interface B{ public abstract void get();}
那么在接口之中,也同样存在了抽象方法,很明显,接口对象无法进行对象的实例化操作,那么接口的使用原则如下:
1、每一个接口必须定义子类,子类使用implement关键字实现接口; 。
2、接口的子类(如果不是抽象类)则必须覆写接口之中所定义的全部抽象方法; 。
3、利用接口的子类,采用对象的向上转型方式,进行接口对象的实例化操作.
在Java之中每一个抽象类都可以实现多个接口,但是反过来讲,一个接口却不能继承抽象类,可是Java之中,一个接口却可以同时继承多个接口,以实现接口的多继承操作.
//因为接口和类的定义命名要求相同,所以为了区分接口和类//建议在所以的接口前面追加一个字母Iinterface IMessage{ public static final String MSG = "www.baidu.com"; public abstract void print();//抽象方法}interface INews{ public abstract String get();}class MessageImpl implements IMessage,INews{ public void print(){ System.out.println("IMessage中print方法:" +IMessage.MSG); } public String get(){ return "INews中get方法:" + IMessage.MSG; }}class NewsImpl implements INews{ public String get(){ return null; }}public class InFa{ public static void main(String args[]){ IMessage ms = new MessageImpl(); //InFa ms.print(); INews m = new MessageImpl(); //INews中get方法:www.baidu.com System.out.println(m.get()); /*Exception in thread "main" java.lang.ClassCastException: NewsImpl cannot be cast to IMessageat InFa.main(InFa.java:33)转换异常 */ INews mn = new NewsImpl(); IMessage m1 = (IMessage) mn; System.out.println(mn.get()); }}
但是需要说明的是:接口之中的全部组成就是抽象方法和全局常量,那么在开发之中一下的两种定义接口的最终效果是完全一样的
。
完整定义:
interface A{ public static final String INFO="接口A"; public abstract void print();}
简化定义:
interface A{//定义接口 public String INFO="接口A"; public void print();}
接口之中所有访问权限只有一种:public,即:定义接口方法的时候就算没写上public,最终也是public. 。
1.在以后的编写接口的时候,大部分的接口里面只会提供抽象方法,很少在接口里面看见许多的全局常量。很多时候防止避免开发者出现混乱,所以接口的方法都会加上public.
2.当一个子类需要实现接口又需要继承抽象类的时候,请先使用extends继承一个抽象类,再使用implements实现多个接口.
//因为接口和类的定义命名要求相同,所以为了区分接口和类//建议在所以的接口前面追加一个字母Iinterface INews{ public String get();//抽象方法}//可以再类上进行明确描述,在以后的开发之中也经常出现以下的命名习惯abstract class AbstractMessage{//只有接口中的abstract中才可以省略,抽象类中的不能省略 public abstract void print();}class NewsImpl extends AbstractMessage implements INews{ public String get(){ return "www.baidu.com"; } public void print(){} //有方法体就叫覆写}public class InFa1{ public static void main(String args[]){ INews news = new NewsImpl(); System.out.println(news.get()); //NewsImpl是抽象类和接口的共同子类 AbstractMessage am = (AbstractMessage) news; am.print(); }}
3.一个抽象类可以使用implements实现多个接口,但是接口不能够去继承抽象类; 。
//因为接口和类的定义命名要求相同,所以为了区分接口和类//建议在所以的接口前面追加一个字母Iinterface INews{ public String get();//抽象方法}//可以再类上进行明确描述,在以后的开发之中也经常出现以下的命名习惯abstract class AbstractMessage implements INews{//只有接口中的abstract中才可以省略,抽象类中的不能省略 public abstract void print();}class NewsImpl extends AbstractMessage{ public String get(){ return "www.baidu.com"; } public void print(){} //有方法体就叫覆写}/*该类的调用相当于孙子实例化爷爷对象 将 爷爷对象转换为儿子对象*/public class InFa1{ public static void main(String args[]){ INews news = new NewsImpl(); System.out.println(news.get()); //NewsImpl是抽象类和接口的共同子类 AbstractMessage am = (AbstractMessage) news; am.print(); }}
实际上此时关系属于三层继承.
。
//因为接口和类的定义命名要求相同,所以为了区分接口和类//建议在所以的接口前面追加一个字母Iinterface INews{ public String get();//抽象方法 public void pirnt(); }//假设一个接口可能有无数个子类,但是对于一个方法的实现是一样的abstract class AbstractMessage implements INews{ public void print(){ System.out.println("www.baidu.com"); }}//生怕别人不知道NewsImpl是INews接口的子类,做一个重复标记而已class NewsImpl extends AbstractMessage implements INews{ public String get(){ return "www.baidu.com"; } public void print(){} //有方法体就叫覆写}/*该类的调用相当于孙子实例化爷爷对象 将 爷爷对象转换为儿子对象*/public class InFa1{ public static void main(String args[]){ INews news = new NewsImpl(); System.out.println(news.get()); //NewsImpl是抽象类和接口的共同子类 AbstractMessage am = (AbstractMessage) news; am.print(); }}
4.一个接口可以使用extends来继承多个父接口.
interface A{ public void pirntA(); }interface B{ public void pirntB(); }interface C extends A,B{ public void pirntC();}class Impl implements C{ public void pirntA(); public void pirntB(); public void pirntC(); }public class InFa1{ public static void main(String args[]){ }}
5.接口可以定义一系列的内部接口,包括:内部普通类、内部抽象类、内部接口,其中使用static定义的内部接口就相当于是一个外部接口 。
而在开发之中,内部类是永远不会受到概念限制的,在一个类中可以定义内部类,在一个抽象类之中也可以抽象内部类,在一个接口里面也可以定义内部抽象类或内部接口.但是从实际的开发来讲用户去定义内部抽象类或内部接口的时候是比较少见的(android开发中见过),而且在定义内部接口的时候如果使用了static,表示一个外部接口.
interface A{ public void printA();static interface B{ //外部接口 public void printB(); }}class X implements A.B{ public void printA(){ System.out.println("A"); } public void printB(){ System.out.println("B"); }}public class Inter{ public static void main(String args[]){ A.B ab = new X(); ab.printB(); }}
。
以上对于接口的概念并不是很难理解,但是需要强调的是,在实际开发之中,接口有三大主要功能:
。
interface USB{ public void install(); //进行安装 public void work(); //进行工作}
。
class Computer{ public void plugin(USB usb){ usb.install(); usb.work(); }}class Flash implements USB{ public void install(){ System.out.println("安装U盘驱动"); } public void work(){ System.out.println("U盘进行工作"); }}class Printer implements USB{ public void install(){ System.out.println("安装打印机驱动"); } public void work(){ System.out.println("打印机进行工作"); }}
。
interface USB{ public void install(); //进行安装 public void work(); //进行工作}class Computer{ public void plugin(USB usb){ usb.install(); usb.work(); }}class Flash implements USB{ public void install(){ System.out.println("安装U盘驱动"); } public void work(){ System.out.println("U盘进行工作"); }}class Printer implements USB{ public void install(){ System.out.println("安装打印机驱动"); } public void work(){ System.out.println("打印机进行工作"); }}public class InFa3{ public static void main(String args[]){ /*安装U盘驱动U盘进行工作安装打印机驱动打印机进行工作 */ Computer cm = new Computer(); cm.plugin(new Flash()); cm.plugin(new Printer()); }}
发现使用接口和对象多态性结合,对于参数的统一更加明确。而且可以发现接口时再类之上的设计.
。
区别 | 抽象类 | 接口 |
---|---|---|
定义关键字 | 使用abstract class进行声明 | 使用interface进行声明 |
组成 | 全局常量、全局变量、构造方法、抽象方法、普通方法 | 全局变量、抽象方法 |
权限 | 可以使用任何权限 | 只能使用public权限 |
关系 | 一个抽象类可以实现多个接口 | 接口不能继承抽象类,却可以继承多个接口 |
使用 | 子类使用extends | 子类使用implements |
设计模式 | 模板设计模式 | 工厂模式、代理模式 |
局限 | 一个子类只能继承一个抽象方法 | 一个子类可以实现多个接口 |
通过上面的分析可以得出结论:在开发之中,抽象类和接口实际上都是可以使用的,并且使用哪一个都没有明确的限制,可是抽象类有一个最大的缺点―一个子类只能够继承一个抽象类,存在单继承的局限,所以当遇到抽象类和接口都可以实现的情况下,优先考虑接口,避免单继承局限.
除了单继承的局限之外,实际上使用抽象类和接口都是类似的,但是在实际的开发中,抽象类的设计比接口的复杂.
。
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我的更多内容! 。
原文链接:https://blog.csdn.net/zsr6135/article/details/119451254 。
最后此篇关于java基础的详细了解第八天的文章就讲到这里了,如果你想了解更多关于java基础的详细了解第八天的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!