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;//时间类
//构造函数必须定义protected
protected 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";
else
return "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;
else
return b;
}
}

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

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;
else
return 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;
else
return 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; @Override
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
} class Account implements Cloneable {
User user;
long balance; @Override
public 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 接口和抽象类区别





参考:

Java探索之旅(11)——抽象类与接口的更多相关文章

  1. 第二十八节:Java基础-进阶继承,抽象类,接口

    前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...

  2. Java编程思想学习(七) 抽象类和接口

    1.抽象类和抽象方法 抽象方法:不完整的,仅有声明而没有方法体. abstract void f(); 抽象类:包含抽象方法的类.(若一个类包含一个或多个抽象方法,则该类必须限定为抽象的.) 1.用抽 ...

  3. Java面向对象 第5节 抽象类和接口

    一.抽象类和抽象方法 区分抽象方法和普通方法1)当一个方法被abstract修饰时,该方法成为抽象方法2)抽象类所在的类必须定义为抽象类3)抽象方法不会有具体的实现,而是在抽象类的子类中通过方法重写进 ...

  4. Java从零开始学十八(抽象类和接口)

    一.什么是抽象类和接口 抽象类.接口与类是一个层次的概念,是java中极其重要的概念. 抽象类是从多个类中抽象出来的公共模板,提供子类均具有的功能. 接口是从多个类中抽象出来的规范,体现的是规范和实现 ...

  5. java类与对象基础--抽象类和接口

    在java的类体系中,有两个比较特殊的抽象体--抽象类和接口.抽象体并不可以拥有具体的对象(而且接口甚至不是类),但是它们却是在java设计领域非常重要的两个概念,很多优秀的设计模式都是基于这两个概念 ...

  6. 牛客网Java刷题知识点之抽象类与接口

    不多说,直接上干货! 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是Java语言中对抽象概念进行定义的两种机制,正是由于它们的存在才赋予java强大的面向对象的能力. ...

  7. 夯实Java基础(十)——抽象类和接口

    转载自:http://cmsblogs.com/ 该博主的网站上干货非常!非常!非常多(说三遍),强烈推荐大家前去学习. 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法 抽象类与接口是 ...

  8. Java基础系列4:抽象类与接口的前世今生

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 1.抽象类: 当编写 ...

  9. Java入门(一)——类、抽象类和接口

    Java是一门面向对象语言,可以看出"对象"在Java有着举足轻重的位置.那么,"对象"从何而来呢?那必须是丈母娘造出来的,下面我们就先来说说这个丈母娘--类. ...

随机推荐

  1. 提供的STC89C52RC单片机GPS在LCD1602液晶只显示welcome to use问题?

    1.使用USB-TTL接GPS单独测试GPS定位在所处环境看是否能定位到. 2.检查自己使用的单片机是不是STC89C52RC型号,提供例程使用的这个型号单片机.如果使用其他51单片机,请先使用STC ...

  2. 用Pythonic方式来思考

    一门语言的编程习惯是由用户来确立的.这些年来,Python开发者用Pythonic这个形容词来描述那种符合特定风格的代码. 这种Pyhtonic风格,既不是严密的规范,也不是由编译器强加给开发者的规则 ...

  3. ubuntu service XXX start启动报start: Rejected send message, 1 matche

    service cron restart命令报错如下: stop: Rejected send message, 1 matched rules; type="method_call&quo ...

  4. LeetCode:长度最小的子数组【209】

    LeetCode:长度最小的子数组[209] 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 ...

  5. 高性能javascript学习总结(1)--加载与运行

    一.脚本的位置         我们知道,一个<script>标签可以放在 HTML 文档的<head>或<body>标签中,但是浏览器是怎么加载和执行这些java ...

  6. PAT 天梯赛 L2-016. 愿天下有情人都是失散多年的兄妹 【BFS】

    题目链接 https://www.patest.cn/contests/gplt/L2-016 思路 用BFS 每层 遍历当代 并且查找当代是否有重复 有重复就跳出 然后 POP 并且将他们的下一代 ...

  7. 牛客小白月赛1 F 三视图 【循环】

    题目链接 https://www.nowcoder.com/acm/contest/85/F 思路 记录每一个面 上的点 是否有方块 然后 根据它的输出顺序 遍历访问 如果有 输出 'X' 否则 输出 ...

  8. QCon2016 上海会议汇总(2) - 团队管理

    QCon 2016上海日程:http://2016.qconshanghai.com/schedule <当你的团队还支撑不起梦想时> - 链尚网技术合伙人 杨荣伟 Figo讲述了如何训练 ...

  9. python的property属性

    最近看书中关于Python的property()内建函数属性内容时<python核心编程>解释的生僻难懂,但在网上看到了一篇关于property属性非常好的译文介绍. http://pyt ...

  10. 【leetcode刷题笔记】Combination Sum

    Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...