Java探索之旅(11)——抽象类与接口

1.Java数据类型

     
     ❶不可变类,是指当创建了这个类的实例后,就不允许修改它的属性值。 它包括:
        Primitive变量boolean,byte, char, double ,float, integer, long, short
        JDK不可变类Boolean, Byte, Character, Double, Float, Integer, Long, Short, String (java.lang包中)
     ❷可变类,是当你获得这个类的一个实例引用时,你可以改变这个实例的内容。 可变类对象间用“=”赋值,则会是使两个对象实际上会引用同一个实例。所以,只有实现深度clone才能使可变类对象的修改不影响原始对象的值。

     ❸对于不可变类,可变类的特性也有意义,有的时候我们不希望重复创建相同的内容的实例。因此,我们也可以利用不可变类获得实例缓存。如:

                Integer a=Integer.valueOf(10);
                Integer b= Integer.valueOf(10);

    只会在第一次创建取值为10的Integer对象。也就是说a和b指向同一处内存上的内容。


2.抽象类

    ❶继承层次结构中。父类通用而不明确,子类越来越明确和具体。接口是定义多个类的共同行为。

    ❷抽象关键字abstract,位置紧随访问修饰符(public,protected,private)之后。

    ❸抽象类的构造函数一律定义为protected。抽象方法只有定义没有实现(一般定义为public,且抽象方法禁止定义为静态方法)。

    ❹包含抽象方法的类必须定义为抽象类。抽象类不一定需要包含抽象方法。

    ❺若子类没有实现父类的抽象方法。子类仍需要定义为抽象类。即,抽象类派生出的非抽象子类,必须实现所有基类的抽象方法,即使它没有使用

    ❺父类为具体类,子类可以是抽象类。子类可以覆盖父类的方法并将其定义为抽象方法,当然前提是子类定义为抽象类。

    ❻new无法作用抽象类创建实例,但是可以作为一种数据类型,创建引用变量(或者引用数组),然后指向子类对象。当然其引用类型也可以作为函数参数。

     如下定义抽象类Gobject。定义两个扩展类圆Circle和长方形rectangle。定义抽象方法getArea()返回面积

package GeometricObject;
public abstract class Gobject {private String color="white";private boolean filled;private java.util.Date dateCreated;//时间类//构造函数必须定义protectedprotected Gobject(){dateCreated=new java.util.Date();}protected Gobject(String s,boolean f){this();filled=f;color=s;}public String toString(){return "Created on:"+dateCreated+"\ncolor:"+color+"\nfilled with?--"+filled;}public void setColor(final String s){color=s;}public String getColor(){return color;}public abstract double getArea();//抽象方法
}//圆类
class Circle extends Gobject implements Comparable,Cloneable{double radius;final static double PI=3.1415;Circle(){radius=1.0;}//隐含调用super();Circle(double r,String s,boolean f){super(s,f);//调用父类构造函数radius=r;}public String toString(){return super.toString()+"\nArea--"+getArea();}
}//长方形类
class rectangle extends Gobject implements Comparable,Cloneable{//常用方法,从虚函数中扩展double width,height;rectangle (){width=height=1.0;}//隐含调用super();rectangle(double w,double h,String s,boolean f){super(s,f);//调用父类构造函数width=w;height=h;}public double getArea(){return width*height;}
}


  测试如下:

public class test {public static void main(String[] args){Gobject[] p=new Gobject[2];//抽象类作为数据类型定义数组p[0]=new Circle(2.3,"Blue",true);p[1]=new rectangle(4.0,5.0,"Red",false);System.out.println(p[0].toString());System.out.println(p[1].toString());System.out.println("The two Object have "+equalArea(p[0],p[1])+" area");public static String equalArea(Gobject o1,Gobject o2)//抽象类引用类型作为函数参数{if(o1.getArea()==o2.getArea())//JVM动态调用实例的函数return "same";elsereturn "different";}
}



3.接口

   ❶类似于类,目的是指明多个对象的共同行为。

   ❷接口类似于抽象类。编译为单独的字节码文件。不能使用new创建实例,但是可以声明引用变量或者作为类型转换的结果。

   ❸接口仅仅包括常量和抽象方法或者完全为空(所谓的标记接口maker interface)。即所有的方法默认都是public abstract,所有的变量都是public final static<

   ❹接口类定义的常量可以使用“接口名.变量名”访问。


4.可比较接口 Comparable

       ❶Java中的许多类,比如String和Data实现(implements)Comparable接口,以比较自然对象的大小。

   ❷接口引用变量可作函数参数类型和返回类型。声明如下:

           public interface Comparable //比较接口{int comparaTo(Object o);//判断当前对象与目标对象的大小}
   定义的通用求最大值的Max函数如下:

//通用的求最大值的类
//接口引用作为函数参数和返回参数,此时类似虚函数
public class Max {public static Comparable max(Comparable a,Comparable b){if(a.comparaTo(b)>0)//调用具体的比较函数return a;elsereturn b;}
}

   Circlerectangle分别实现了该接口,即继承了接口的抽象方法,并具体实现。如下:

class Circle extends Gobject implements Comparable,Cloneable{......................public int comparaTo(Object o){//继承并且实现camparaTo函数if(getArea()>((Gobject)o).getArea())//显式转换return 1;else if(getArea()<((Gobject)o).getArea())return -1;elsereturn 0;}.................
}class rectangle extends Gobject implements Comparable,Cloneable{//常用方法,从虚函数中扩展..................public int comparaTo(Object o){//继承并且实现camparaTo函数if(getArea()>((Gobject)o).getArea())return 1;else if(getArea()<((Gobject)o).getArea())return -1;elsereturn 0;}.....................
}

    利用Max求两个圆或者两个长方体最大的面积的代码片段为

	//Comparable 接口//使用通用的Max类,比较任意扩展了comparable的对象Circle[] cp=new Circle[2];cp[0]=new Circle(1.56,"Blue",true);cp[1]=new Circle(3.45,"Green",false);Comparable max=Max.max(cp[0], cp[1]);//接口类型引用System.out.println("The max Area of 2 Circle is "+((Circle)max).getArea());//显式转换rectangle[] rp=new rectangle[2];rp[0]=new rectangle(1.56,12.0,"Blue",true);rp[1]=new rectangle(3.45,6.7,"Green",false);Comparable max1=Max.max(rp[0], rp[1]);//接口类型引用System.out.println("The max Area of 2 rectangle is  "+((rectangle)max1).getArea());//显式转换  

   由于max输出的类型为Comparable类型,所以调用Circle或者rectangle的getArea()函数必须显式转换


5.可克隆接口 Cloneable

   ❶该接口为标记接口,即无常量和方法。标记用来表示类拥有某种属性。定义如下:

public interface Cloneable 
{}

    ❷对于可复制的类,必须满足:
     实现Cloneable接口。这样才有资格调用Object.clone()方法
      覆盖Object的clone()方法。Object.clone()方法是protected的,覆盖并改为public

   ❸Object的clone的行为是最简单的。以堆上的内存存储解释的话(不计内存),对一个对象a的clone就是在堆上分配一个和a在堆上所占存储空间一样大的一块地方,然后把a的堆内存的内容按位(bit-wise)复制到这个新分配的内存。

   ❹Primitive数据类型(如int,double)为深拷贝,引用类型(包括可变类和不可变类)均为浅拷贝,浅拷贝指拷贝前后引用变量指向同一对象。深拷贝或者克隆的目的在数据前后隔离,默认的浅copy不是隔离的——即改变copy的东西,会影响到原型的内部。

   ❺改变拷贝对象的Primitive数据值或者不可变类引用变量(如String)的指向对象,不影响源对象的对应数据,即满足数据隔离。前者的原因显而易见,后者的原因是因为---不可变类不能通过【对象名+"."方法(数据)】改变数据域,只能通过将其指向其他对象改变其数据域,如此一来,肯定不影响。具体点击

   对于前面定义的Circle,rectangle类,实现Coloneable接口如下:

class Circle extends Gobject implements Comparable,Cloneable{......................public Object clone() throws CloneNotSupportedException{return super.clone();}......................}//长方形类
class rectangle extends Gobject implements Comparable,Cloneable{//常用方法,从虚函数中扩展.......................public Object clone() throws CloneNotSupportedException{return super.clone();}.......................
}
 注意

    ①由于返回的为Object,可能需要显式转换。

    ②使用super.clone()而非this.clone()的原因。Object中的clone执行的时候使用了RTTI(run-time type identification)的机制,动态得找到目前正在调用clone方法的reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy的目的。所以调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。根本没有必用调用this.clone()

    ③如果需要克隆的类引用到了其它的类的对象,甚至这个对象也引用到了别的对象,那么在必要情况下,你需要将这个对象树进行完整的克隆。如下:

class User implements Cloneable {String name;int age;@Overridepublic User clone() throws CloneNotSupportedException {return (User) super.clone();}
}class Account implements Cloneable {User user;long balance;@Overridepublic Account clone() throws CloneNotSupportedException {Account account = (Account) super.clone();if (user != null) {account.user = user.clone();//显式深拷贝}return account;}
}

6.抽象类和接口的比较

   ❶变量:抽象类无限制;接口必须为public static final
   ❷构造方法:抽象类子类经过构造链调用构造法。接口无构造方法。两者均不能用new实例化
   ❸方法:抽象类无限制;接口必须是public abstract
   ❹抽象类只能(被)单一扩展;类可以同时实现多重接口,接口同时可以同时继承多重接口而不是类。
   ❺所有类有公共根Object;而所有接口没有公共接口。
   ❻两者均可以定义类型,且引用变量可以引用---任何实现了接口(或抽象类)的对象。
    一般而言,父子关系强,使用抽象类;弱使用接口。接口可以定义不相关类共有的父类型(例如房屋可以比较面积,数值可以比较大小,使用comparable接口)。抽象类更加使用方便,接口更加灵活。
   注意: 如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法。接口做不到这一点,如果向一个Java接口里加入一个 新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行,这显然是Java接口的缺点之一。 
               经典的使用方法
A extends AbstractB implements interfaceC
详细可点击:Java 接口和抽象类区别




参考:
    1.深入理解java的clone
    2.java.lang.Cloneable接口
    3.Java的clone机制及其可变类与不可变类

转载于:https://www.cnblogs.com/engineerLF/p/5393089.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LOJ #6052. 「雅礼集训 2017 Day11」DIV

完了我是数学姿势越来越弱了&#xff0c;感觉这种CXRdalao秒掉的题我都要做好久 一些前置推导 首先我们很容易得出\((abi)(cdi)k \Leftrightarrow ac-bdk,adbc0\) 我们可以直接\(adbc0\Rightarrow ad-bc\Rightarrow \frac{a}b-\frac{c}{d}\) 考虑把这个分数化为最简的形式&…

移动端页面不需要在meta加_移动端适配viewport缩放方案

1. 前言设计师交付给前端开发一张宽度为750px的视觉稿&#xff0c;设计稿上元素的尺寸、颜色、位置等已做过标注&#xff0c;要求工程师工在适配不同屏幕尺寸的设备时采用等比缩放的方案。采用viewport缩放的方案能又快又好的实现需求。2. 原理在写HTML、CSS对设计稿进行还原时…

(转)用 Fiddler 看看 UpdatePanel 发生了什么

第一个 ASP.NET AJAX 程序&#xff1a;UpdatePanel一文中介绍了 UpdatePanel 实现 Ajax&#xff0c;我们今天利用 Fiddler 来看看 UpdatePanel 发生了什么。 实验步骤 启动 Fiddler&#xff0c;访问我们事先写好的 UpdatePanel 网页&#xff08;注意不要用 127.0.0.1 或 localh…

转载:div和flash层级关系问题

转自&#xff1a;http://sin581.blog.163.com/blog/static/860578932012813112334404/问题&#xff1a;ie下默认好像div层级没有flash层级高&#xff0c;也就是当div绝对相对压在flash上&#xff0c;压不住flash总是在最上面显示&#xff0c;请给出方案 或者说下大概如何解决 用…

基于Google Reader发展起来的个性化推荐系统之三大问题

郑昀玩聚SR 20091003 中科院的xlvector(即项亮&#xff0c;他所在的团队The Ensemble在7月份获得Netflix大奖赛公开测试排名第一&#xff0c;但在9月22日Netflix宣布BPC获胜&#xff0c;原因据说只是因为项亮他们提交结果晚了20分钟)最近发布了一个小工具GRSuggest&#xff0c;…

直接从chrome中复制的body到postman中希望能自动识别去除空格

Describe the bug直接从chrome开发者工具中request的body复制到postman中时会带有空格&#xff0c;需要手动删除空格。 To Reproduce1、使用chrome开发者工具抓取一个post请求2、复制请求中参数3、粘贴到postman的body中 Expected behavior3、把带的空格删除掉 转载于:https://…

气象ts评分_给大家分享一个格点插值到站点然后TS评分的程序

登录后查看更多精彩内容~您需要 登录 才可以下载或查看&#xff0c;没有帐号&#xff1f;立即注册x!****************************************************************************!! PROGRAM: T639格点资料插值成站点资料!!**********************************************…

RichTextBox 右键显示 ContextMenuTrip

说明&#xff1a; (1)命名&#xff1a; RichTextBox -> rtxt1 ContextMenuTrip -> cms1 (2)截图&#xff1a; (3)完整代码&#xff1a; <span style"font-size:14px;">using System; using System.Collections.Generic; using System.ComponentModel; u…

设计模式学习笔记--Mediator 中介者模式

我们知道面向对象应用程序是由一组为了提供某种服务而彼此交互的对象组成。当彼此引用的对象数量比较少时&#xff0c;此时对象之间就为直接交互&#xff08;点对点)。而当对象的数量增加时&#xff0c;这种直接交互会导致对象之间复杂的、混乱的引用,最后形成一张巨大的网&…

Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验

vee-validate 是为 Vue.js 量身打造的表单校验框架&#xff0c;允许您校验输入的内容并显示对应的错误提示信息。它内置了很多常见的校验规则&#xff0c;可以组合使用多种校验规则&#xff0c;大部分场景只需要配置就能实现开箱即用&#xff0c;还支持自定义正则表达式。而且支…

python微博自动评论转发_python3 调用新浪微博api实现自动发布评论

新浪微博开放平台提供了丰富的API接口&#xff0c;利用这些接口&#xff0c;开发者能够开发出独具特色的微博应用。但是&#xff0c;大部分接口都需要用户授权给应用&#xff0c;应用利用授权得到的Access Token来调用相应的接口来获取内容。新浪微博的授权机制目前主要有3种应…

Linux中fork()函数详解

参考地址 1.对fork函数的认识&#xff1a; 一个进程&#xff0c;包括代码、数据和分配给进程的资源。fork&#xff08;&#xff09;函数通过系统调用创建一个与原来进程几乎完全相同的进程&#xff0c; 也就是两个进程可以做完全相同的事&#xff0c;但如果初始参数或者传入的变…

类似pyinstaller_Python 打包工具对比,Nuitka vs Pyinstaller

py2exe&#xff0c;Pyinstaller&#xff0c;Cx_freeze&#xff0c;Nuitka都可以完成python打包的任务。Pyinstaller和Nuitka都号称跨平台&#xff0c;但其实顶多只能算是工具本身跨平台&#xff0c;实际体验中不仅打包产生的文件不能跨平台&#xff0c;能否成功打包本身也不确定…

Android学习之PopupWindow

Android的对话框有两种&#xff1a;PopupWindow和AlertDialog。 详细说明如下&#xff1a; AlertDialog是非阻塞式对话框&#xff1a;AlertDialog弹出时&#xff0c;后台还可以做事情&#xff1b; AlertDialog的位置固定&#xff0c;而PopupWindow的位置可以随意&#xff1b; A…

spring整合mybatis接口无法注入问题

在学习Spring完之后简单的了解了MyBatis。然后进行简单的整合&#xff0c;遇到MyBatista接口映射的Bean无法自动注入的问题&#xff1b; 代码异常&#xff1a; 线程“main”org.springframe .bean .factory中的异常。创建名为“UserController”的bean时出错:通过字段“userdao…

LR重新安装的问题

LR的安装&#xff0c;说难不难&#xff0c;说易也不易。在此就把我安装时碰到的问题记录下来&#xff0c;以供大家参考。 第一次安装时&#xff0c;我是成功了的。&#xff08;注意&#xff1a;安装程序的目录不能有中文&#xff0c;当然同时你得有lincense&#xff09; 后来因…

matlab柱状斜线_Matlab小练习:按斜线方向依次赋值矩阵

来自知乎问题&#xff0c;觉得挺有意思&#xff0c;留给学生解答之余&#xff0c;我也做了一番思考&#xff0c;得到三种解法。题目如下&#xff1a;以n80为例&#xff0c;————————————————————一、先要根据确定矩阵的阶数 如果先生成足够大矩阵&#xff0…

Programming C#.Classes and Objects.只读字段

只读字段 当字段声明中含有 readonly 修饰符时&#xff0c;该声明所引入的字段为只读字段。给只读字段的直接赋值只能作为声明的组成部分出现&#xff0c;或在同一类中的实例构造函数或静态构造函数中出现。&#xff08;在这些上下文中&#xff0c;只读字段可以被多次赋值。&am…

会计知识

毛利 等于收入纯利 等于利润 按照&#xff1a;利润&#xff1d;收入-成本-费用 收入&#xff1a;收到的现金、支票、签单金额成本&#xff1a;买材料、酒水、电、工资、等费用&#xff1a;日租金、桌椅、碗、盘子等摊销、税金等等 ------------------------------------------…

2020-12-21

蜂鸣器&#xff08;向导辅助&#xff09; /******************************************************* This program was created by the CodeWizardAVR V3.12 Advanced Automatic Program Generator ?Copyright 1998-2014 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpin…