马士兵课程笔记(续2)

J2SDK中主要的包介绍 

 位置%JAVAHOME%\jre\lib\rt.jar, rt: runtime, 这个jar文件意为虚拟机运行时必用到的那些包. 

 CMD下将类文件达成jar包的方法: 在最上层包所在目录下输入命令jar -cvf xx.jar *.*

 使用打好的jar包: 把jar文件的全路径名添进%CLASSPATH% 即可。

 

java.lang

包含一些Java语言的核心类(如String, System, Math, Integer和Thread等), 提供常用功能. 唯有java.lang包无需import, 直接使用.

java.awt

包含了构成抽象窗口工具集(abstract window toolkits)的多个类, 用于构建和管理应用程序的图形用户界面(GUI).

java.applet

已经不常用. 包含applet运行所需的一些类.

java.net

包含执行与网络相关的操作的类.

java.io

包含能提供多种输入输出功能的类.

java.util

包含一些实用工具类, 如定义系统特性, 使用与日期日历相关的函数等.

 

类的继承与权限控制

继承

extends关键字

java只支持单继承,不允许多继承(接口代之)

访问控制

private     ——类内部(子类对这样成员只能看不能用)

default     ——同一个包

protected ——子类

public       ——

对class的权限修饰只可以用public和default(但四种都可用于修饰内部类)。

 

方法的重写overwrite

在子类中可以根据需要对从基类中继承来的方法进行重写;

重写方法必须和被重写方法具有相同方法名、参数列表和返回类型(注意与重载的区别);

Tips:为保证同名,建议用复制粘贴。

重写方法不能使用比被重写方法更严格的访问权限

 

super

引用基类的成分(对比this)

子类中定义的与父类中的成员变量重名的成员变量是两个存储空间, 可用super引用来区分开

 

继承中的构造方法

  • 子类的构造过程中必然调用其父类的构造方法
  • 子类可以在自己的构造方法第一句显式地添加 super(argument_list) 语句调用父类的构造方法

tips: this(argument_list) 则是调用本类其他重载的构造方法

  • 缺省情况下, 系统默认调用父类无参数的构造方法
  • 如果子类构造方法中既没有显式地调用父类构造方法, 而父类中又没有无参数的构造方法, 则会编译出错

Object类

  • 是所有Java类的唯一的根基类 (C++有很多);
  • 缺省时, 都默认是Object类的子类;
  • 位于%JAVAHOME%\jre\lib\rt.jar\com\sun\java\lang\Object.class
  • Object类的方法也是所有类都继承的基本方法: clone(), equals(), finalize(), getClass(), hashCode(), notify(), notifyAll(), toString(), wait();
  • toString()方法 在类对象与String的连接操作时如
System.out.println("Object is " + (new Object()));

  时, 被自动调用; 

  Object类的toString方法返回值由此对象类名加"@"加此对象哈希码的无符号十六进制表示组成, 即: 

getClass().getName() + "@" + Integer.toHexString(hashCode())

  且Sun建议所有类都重写它

  重写equals()方法需要注意检查传参的引用值非空以及类型检查

  比较这两种写法:

// 类型检查1
class C {
    int i;
    String j;

    public boolean equals(Object o) {
        if (null == o) return false;
        if (o instanceof C) {
            C c = (C) o;
            return this.i == c.i && this.j.equals(c.j);
        }
        return false;
    }
}

// 类型检查2
...
public boolean equals(C o) {
    if (null == o) return false;
    return this.i == o.i && this.j.equals(o.j);
}
...
 结论:第二段是错误的写法,原因见 http://nudtgk2000.iteye.com/blog/1455669

         父类与子类的equals比较...推理很简单, 实验证明也成立.

  Tips: String类型在如下情况可用"=="判断相等:

 

String a = "hello";    // 因为"hello"在 data segment 中只有唯一的字符串常量,  
String b = "hello";    // 也就是说a和b的确引用的是同一个地址
System.out.println(a == b);

String c = new String("hello");    // 但是,这样写就是new出来了两个对象,
String d = new String("hello");    // 两个地址不会一样
System.out.println(c == d);

// 输出: true
//         false

对象转型casting

  • 一个基类的引用类型变量可以"指向"其子类的对象;
Animal a = new Bird();    // 这是可以的 
  • 一个基类的引用不可访问其子类对象新增加的成员(属性和方法);
// 续上语句
a.fly();    // 这是不行的, 因为现在把a视为一般动物了, 在内存上a实际上仅指向Bird类对象中Animal的那部分.
  • 可以使用 "应用变量 instanceof 类名" 来判断该引用类型变量所"指向"的对象是否属于该类或该类的子类;
a instanceof Animal;   // true
a instanceof Bird;    // true
  • 父类引用子类对象称作向上转型(upcasting), 反之称为向下转型(downcasting)(或者称为强制转换).
  • 可扩展性 -- 子类对象做为父类引用参数传入方法
public f(Animal o) {...};
...
f(bird);
f(fish);
f(snake);
...
 

 

动态绑定Dynamic Binding(多态Polymoph, Late Binding)

    面向对象的核心机制

    动态绑定是指在执行期间(而非编译期)判断所引用对象的实际类型, 根据其实际的类型调用相应的方法.

    优点: 最好地支持了可扩展性

    class Animal {

    private String name;
    Animal(String name) {this.name = name}

    public void enjoy() {
        System.out.println("叫声");
    }
}

class Cat extends Animal {
    private String eyeColor;
    Cat(String a, String c) {
        super(a);
        eyeColor = c;
    }

    public void enjoy() {                  // 重写
        System.out.println("猫叫");
    }
}

class Dog extends Animal {
    private String furColor;
    Cat(String a, String f) {
        super(a);
        furColor = f;
    }

    public void enjoy() {                  // 重写
        System.out.println("狗叫");
    }
}

class Lady {
    private String name;
    private Animal pet;                    // 定义成父类类型能带来最大的灵活性
    Lady(String name, Animal pet) {
        this.name = name;
        this.pet = pet;
    }

    public void myPetEnjoy() {
        pet.enjoy();
    }
}

public class Test {
    public static void main(String args[]) {
        Cat c = new Cat("catname", "blue");
        Dog d = new Dog("dogname", "black");
        Lady l1 = new Lady("l1", c);
        Lady l2 = new Lady("l2", d);

        l1.myPetEnjoy();
        l2.myPetEnjoy();
    }
}

/** 输出
 *   猫叫
 *   狗叫
 */

      上面的例子中,根据Lady对象的成员变量pet所引用的不同的实际类型而调用相应的enjoy方法

   三个必要条件

  1. 继承
  2. 重写
  3. 父类引用指向子类对象

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值