发表于: 2017-10-31 01:39:11

1 833


今天完成的事情:

现在大概了解RMI是干什么的了  在网上查了很多只是有简单的demo

然后也看了前面师兄的小课堂 感觉收获不大

现在的问题是我知道这个东西一些皮毛的东西  但是不会再自己的代码里面用到他

我不知道怎么把service分离出来

然后还有一个web客户端我不知道写在哪  感觉脑子一片混乱



今天照常继续看了java基础

继承

类、超类和子类

is-a”关系是继承的一个明显特征,关键字extends表示继承。例如:

class Manager extends Employee{
    .... // Manager类继承了Employee类
}

关键字extends表明正在构造的新类派生于一个已存在的类。已存在的类被称为超类(superclass)基类(base class)父类(parent class);新类被称为子类(subclass)派生类(derived class)孩子类(child class)。超类和子类是Java程序员最常用的两个术语。

在通过扩展超类定义子类的时候,仅需要指出子类与超类的不同之处。因此在设计类的时候,应该将通用的方法放在超类中,而将具有特殊用途的方法放在子类中。

若超类中的某些方法对于子类中并不适用,就需要提供一个新的方法来覆盖(override)超类中的这个方法。但如果在这个新的方法中需要调用超类中的同名方法的时候,可以用super来调用,例如:

public double getSalary(){
    double baseSalary = super.getSalary();
    return baseSalary + bonus;
}

在子类中可以增加域、增加方法或覆盖超类的方法,然而绝不能删除继承的任何域和方法。
super在构造器中用来调用超类的构造器,例如:

public Manager( String n, double s, int year ){
    super( n, s, year );
    bonus = 0;
}

如果子类的构造器没有显式地调用超类的构造器,则将自动地调用超类默认的构造器。如果超类没有不带参数的构造器,并且在子类的构造器中又没有显式地调用超类的其他构造器,则Java编译器将报告错误。

继承并不仅限于一个层次,由一个公共超类派生出来的所有类的集合被称为继承层次(inheritance hierarchy)。在继承层次中,从某个特定的类到其祖先的路径被称为该类的继承链(inheritance chain)

通常,一个祖先类可以拥有多个子孙继承链。Java不支持多继承。

有一个用来判断是否应该设计为继承关系的简单规则,这就是is-a规则,它表明子类的每个对象也是超类的对象。

is-a规则的另一种表述方式是置换法则。它表明程序中出现超类对象的任何地方都可以用子类对象置换。

在Java程序设计语言中,对象变量是多态的。一个超类变量既可以引用一个超类对象,也可以引用一个此超类的任何一个子类的对象。然而,不能将一个超类的引用赋给子类变量。

弄清调用对象方法的执行过程十分重要。下面是调用过程的描述:

编译器查看对象的声明类型和方法名。假设调用x.f(param),且隐式参数x声明为C类的对象。编译器将会一一列举所有C类中名为f的方法和其他超类中访问属性为public且名为f的方法。

至此,编译器已获得所有可能被调用的候选方法。

接下来,编译器查看调用方法时提供的参数类型。如果在所有名为f的方法中存在一个与提供的参数类型完全匹配,就选择这个方法。这个过程被称为重载解析(overloading resolution)。如果编译器没有找到与参数类型匹配的方法,或者发现经过类型转换后有多个方法与之匹配,就会报告一个错误。

至此,编译器已获得需要调用的方法名字和参数类型。

如果是private方法、static方法、final方法或者构造器,那么编译器可以准确地知道应该调用哪个方法,这种调用方式称为静态绑定(static binding)。与此对应的是,调用的方法依赖于隐式参数的实际类型,并且在运行时实现动态绑定。

当程序运行,并且采用动态绑定调用方法时,虚拟机一定调用与x所引用对象的实际类型最合适的那个类的方法。

每次调用方法都要进行搜索,时间开销相当大。因此,虚拟机预先为每个类创建了一个方法表(method table),与C++中的VTABLE类似,其中列出了所有方法的签名和实际调用的方法。实际调用时查找此表即可。

动态绑定有一个非常重要的特性:无需对现存的代码进行修改,就可以对程序进行扩展。

不允许扩展的类被称为final类。如果在定义类的时候使用了final修饰符就表明这个类是final类。可以阻止人们定义其子类,如:

final class Executive extends Manager{...}

类中的方法也可以被声明为final如果这样做,子类就不能覆盖这个方法(final类中的所有方法自动成为final方法)。如:public final int getValue()

将方法或类声明为final的意义在于:确保它们不会在子类中改变语义。

对象引用的转换语法与数值表达式的类型转换类似,仅需要用一对圆括号将目标类名括起来,并放置在需要转换的对象引用之前就可以了。

在进行类型转换之前,先查看以下是否能够成功地转换。可以简单地使用instanceof运算符实现,如:

if( staff[1] instanceof Manager){
    boss = (Manager) staff[1];
    ......
}

综上所述,有两个原则:

  1. 只能在继承层次内进行类型转换。
  2. 在超类传唤成子类之前,应该使用instanceof检查。

一般情况下,应该尽量少用类型转换和instanceof运算符。

如果自下而上仰视类的继承层次结构,位于上层的类更具有通用性,甚至可能更加抽象。从某种角度看,祖先类更加通用,人们只将它作为派生其他类的基类,而不作为想使用的特定实例类。

使用abstract关键字来声明抽象类。

public abstract String getDescription();
// no implementation required

为了提高程序的清晰读,包含一个或多个抽象方法的类本身必须被声明为抽象的。除了抽象方法之外,抽象类还可以包含具体数据和具体方法。

抽象方法充当占位的角色,它们的具体实现在子类中。扩展抽象类可以有两种选择。一种是在子类中定义部分抽象方法或抽象方法也不定义,这样就必须将子类也标记为抽象类;另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了。

类即使不含抽象方法,也可以将类声明为抽象类。

抽象类不能被实例化,即不能创建抽象类的对象。但是可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象。

  • 仅对本类可见──private。
  • 对所有类可见──public。
  • 对本包和所有子类可见──protected。
  • 对本包可见──默认。

Java中的protected概念要比C++中的安全性差。

Object 所有类的超类

Object类是Java中所有类的最终祖先,在Java中每个类都是由它扩展而来的。如果没有明确地指出超类,Object就被认为是这个类的超类。

可以使用Object类型的变量引用任何类型的对象。当然,Object类型的变量只能用于作为各种值的通用持有者。要想对其中的内容进行具体的操作,还需要清楚对象的原始类型,并进行相应的类型转换。

在Java中,只有基本类型(primitive types)不是对象。

Object类中的equals方法用于检测一个对象是否等于另一个对象。在Object类中,这个方法将判断两个对象是否具有相同的引用。

Java语言规范要求equals方法具有下面的特性:

  • 自反性:对于任何非空引用xx.equals(x)应该返回true
  • 对称性:对于任何引用xy,当且仅当y.equals(x)返回truex.equals(y)也应该返回true
  • 传递性:对于任何引用xyz,如果x.equals(y)返回truey.equals(z)返回truex.equals(z)也应该返回true
  • 一致性:如果xy引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果。
  • 对于任意非空引用xx.equals(null)应该返回false

可以从两个截然不同的情况看待getClass的使用:

  1. 如果子类能够拥有子集的相等概念,则对称性需求将强制采用getClass进行检测。
  2. 如果由超类决定相等的概念,那么就可以使用instanceof进行检测,这样就可以在不同子类对象之间进行相等的比较。

下面给出编写一个完美的equals方法的建议:

  • 显式参数命名为otherObject,稍后需要将它转换称另一个叫做other的变量。
  • 检测thisotherObject是否引用同一个对象:if( this == otherObject ) return true;
  • 检测otherObject是否为null,如果为null,返回falseif( otherObject == null ) return false;
  • 比较thisotherObject是否属于同一个类。
  • 如果equals语义在每个子类中有所改变,就使用getClass检测:if (getClass() != otherObject.getClass()) return false;
  • 如果所有的子类拥有统一的语义,就使用instanceof检测:if( ! ( otherObject instanceof ClassName )) return false;
  • otherObject转换相应的类型变量:ClassName other = ( ClassName )otherObject;

现在开始对所有需要比较的域进行比较。使用 == 比较基本类型域,使用equals比较对象域。如果所有都匹配,就返回true,否则返回false

return field1 == other.field1
    && field2.equals(other.field2)
    && ...;

如果在子类中重新定义equals,就要在其中包含调用super.equals(other)

散列码(hash code)是由对象导出的一个整型值,是没有规律的。可以用做来判断对象是否相等。

java.lang.Object

  • int hashCode()
    • 返回对象的散列码。散列码可以是任意的整数,包括正数或负数。两个相等的对象要求返回相等的散列码。
  • Class getClass()
    • 返回包含对象信息的类对象。Java提供了类运行时的描述,被封装在Class类中。
  • boolean equals( Object otherObject )
    • 比较两个对象是否相等,如果两个对象指向同一块存储区域,方法放回true;否则方法返回false。在自定义类中,应该覆盖这个方法。
  • String toString()
    • 返回描述该对象值的字符串。在自定义类中,应该覆盖这个方法。
  • Object clone()
    • 创建一个对象的副本。Java运行时系统将为新实例分配存储空间,并将当前的对象复制到这块存储区域中。

java.lang.Class

  • String getName()
    • 返回这个类的名字。
  • Class getSuperclass()
    • 以Class对象的形式返回这个类的超类信息。

Object中还有一个重要的方法,就是toString方法,它用于返回表示对象值的字符串。绝大多数的toString方法都遵循这样的格式:类的名字,随后是一对方括号括起来的域值。

如果x是任意一个对象,并调用System.out.println(x); 就会直接调用x.toString(),并打印输出得到的字符串。

这些大概就我看的东西的梗概


明天的计划:继续学习基础部分  然后争取跟师兄沟通下  把任务8指导下 毕竟不是什么很抽象很难的东西快点做完补基础


遇到的问题:真的是不知道该怎么操作。。 这个很烦恼


收获:java基础部分   今天对于RMI的学习感觉没有多大长进

效率上的话肯定是比前段日子要好得多  没怎么分心


任务进度:任务8步骤1

任务开始时间:2017-10-28

预计结束时间:2017-11-5

禅道:http://task.ptteng.com/zentao/task-view-10472.html




返回列表 返回列表
评论

    分享到