工作日志 5.4、5.5

来源:互联网 发布:网站数据分析方法 编辑:程序博客网 时间:2024/05/16 01:27

这两天学习了疯狂Java讲义的第五章和第六章的一部分:

一、引用变量的强制类型转换

    类型转换运算符是小括号,用法如下:(type)variable。

    进行强制类型转换时需要注意:

    1.基本类型之间的转换只能在数值类型之间进行,这里所说的数值类型包括整数型、字符型和浮点型。但数值型不能和布尔型之间进行类型转换。

    2.引用类型之间的转换只能把一个父类变量转换成子类类型,如果是两个没有任何继承关系的类型,则无法进行类型转换。

    在进行类型转换之前,先用instanceof运算符判断是否可以成功转换,从而避免出现异常。


二、instanceof运算符

    Instanceof运算符的前一个操作数通常是一个引用类型的变量,后一个操作数通常是一个类(也可以是接口),它用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是,则返回true,否则返回false。

    在使用instanceof运算符时需要注意:instanceof运算符前面操作数的编译时类型要么与后面的类相同,要么是后面类的父类,否则会引起编译错误。


三、利用组合实现复用

class Animal{private void beat(){System.out.println("心脏跳动...");}public void breath(){beat();System.out.println("吸一口气,吐一口气,呼吸中...");}}class Bird{private Animal a;public Bird(Animal a){this.a = a;}public void breath(){a.breath();}public void fly(){System.out.println("我在天空自在的飞翔...");}}class Wolf{private Animal a;public Wolf(Animal a){this.a = a;}public void breath(){a.breath();}public void run(){System.out.println("我在陆地上快速奔跑...");}}public class TestComposite{public static void main(String[] args){Animal a1 = new Animal();Bird b = new Bird(a1);b.breath();b.fly();Animal a2 = new Animal();Wolf w = new Wolf(a2);w.breath();w.run();}}

    继承是对已有的类做一番改造,以此获得一个特殊的版本,就是将一个较为抽象的类改造成能适用于某些特定需求的类。如果两个类之间有明确的整体、部分关系,则应该采用组合关系实现复用。


四、单例类

    如果一个类始终只能创建一个实例,则这个类被称为单例类。

    为了避免其他类自由创建该类的实例,我们把该类的构造器使用private修饰,从而把该类的所有构造器隐藏起来。

    根据良好封装的原则:一旦把该类的构造器隐藏起来,则需要提供一个public方法作为该类的访问点,用于创建该类的对象,且该方法必须使用static修饰(因为调用该方法之前还不存在对象,因此调用该方法的不可能是对象,只能是类)。

    除此之外,该类还必须缓存已经创建的对象,否则该类无法知道是否曾经创建过对象,也就无法保证只创建一个对象。为此该类需要使用一个属性来保存曾经创建的对象,因为该属性需要被上面的静态方法访问,故该属性必须使用static修饰。

class Singleton{//使用一个变量来缓存曾经创建的实例private static Singleton instance;//将构造器使用private修饰,隐藏该构造器private Singleton(){}//提供一个静态方法,用于返回Singleton实例//该方法可以加入自定义的控制,保证只产生一个Singleton对象public static Singleton getInstance(){//如果instance为null,表明还不曾创建Singleton对象//如果instance不为null,则表明已经创建了Singleton对象,将不会执行该方法if(instance == null){//创建一个Singleton对象,并将其缓存起来instance = new Singleton();}return instance;}}public class TestSingleton{public static void main(String[] args){//创建Singleton对象不能通过构造器,只能通过getInstance方法Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();//将输出trueSystem.out.println(s1 == s2);}}

五、final修饰符

    final关键字可用于修饰类、变量和方法,表示它修饰的类、方法和变量不可改变。

1.final修饰成员变量

    成员变量是随类初始化或对象初始化而初始化的。对于final修饰的成员变量而言,一旦有了初始值之后,就不能被重新赋值。所以成员变量只能在定义该成员变量时指定默认值,或者在静态初始化块、初始化块和构造器为成员变量指定初始值。

    final成员变量必须显示初始化,系统不会对final成员进行隐式初始化。

2.final修饰局部变量

    final修饰的局部变量可以在定义时指定默认值,也可在后面代码中对其赋值。

    由final修饰的形参不能被赋值。

3.final修饰引用类型变量

    使用final修饰的引用类型变量不能被重新赋值,但可以改变引用类型变量所引用对象的内容。

4.final方法

    final修饰方法不可被重写。

5.final类

    final修饰的类不可有子类。

6.不可变类

    不可变类的意思是创建该类的实例后,该实例的属性是不可变的。

    创建自定义的不可变类,可遵循以下规则:

*  使用private和final修饰符来修饰该类的属性。*  提供带参数构造器,用于根据传入参数来初始化类里的属性。

*  仅为该类的属性提供getter方法,不要为该类的属性提供setter方法,因为普通方法无法修改final修饰的属性。

*  如果有必要,重写Object类中的hashCode和equals方法。在equals方法根据关键属性来作为两个对象相等的标准,除此之外,还应该保证两个用equals方法判断为相等的对象的hashCode也相等。

public class Address{private final String detail;private final String postCode;//在构造器里初始化两个实例属性public Address(){this.detail = "";this.postCode = "";}public Address(String detail , String postCode){this.detail = detail;this.postCode = postCode;}//仅为两个实例属性提供getter方法public String getDetail(){return this.detail;}public String getPostCode(){return this.postCode;}//重写equals方法,判断两个对象是否相等public boolean equals(Object obj){if (obj instanceof Address){Address ad = (Address)obj;if(this.getDetail().equals(ad.getDetail()) && this.getPostCode().equals(ad.getPostCode())){return true;}}return false;}public int hashCode(){return detail.hashCode() + postCode.hashCode();}}

六、抽象类

    抽象方法是只有方法签名,没有方法实现的方法。抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。

    抽象方法和抽象类的规则如下:

*  抽象类和抽象方法必须使用abstract修饰符来修饰。

*  抽象方法不能有方法体,抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。

*  抽象类可以包含属性、方法(包括普通方法和抽象方法)、构造器、初始化块、内部类、枚举类六种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。

*  含有抽象方法的类(包括直接定义了一个抽象方法;继承了一个抽象父类,但没有完全实现父类包含的抽象方法;以及实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。

    当abstract修饰类时,表明这个类只能被继承;当abstract修饰方法时,表明这个方法必须由子类提供实现(即重写)。

    final和abstract不能同时使用,static和abstract不能同时修饰某个方法。

public abstract class Shape{{System.out.println("执行Shape的初始化块...");}private String color;//定义一个计算周长的抽象方法public abstract double calPerimeter();//定义一个返回形状的抽象方法public abstract String getType();//定义Shape的构造器,该构造器并不是用于创建Shape对象,而是用于被子类调用public Shape(){}public Shape(String color){System.out.println("执行Shape的构造器...");this.color = color;}public void setColor(String color){this.color = color;}public String getColor(){return this.color;}}



public class Triangle extends Shape{//定义三角形的三边private double a;private double b;private double c;public Triangle(String color ,double a ,double b ,double c){super(color);this.setSides(a,b,c);}public void setSides(double a ,double b ,double c){if(a>=b+c || b>=a+c || c>=a+b){System.out.println("三角形两边之和必须大于第三边");return;}this.a = a;this.b = b;this.c = c;}//重写Shape类的计算周长的抽象方法public double calPerimeter(){return a+b+c;}//重写Shape类的返回形状的抽象方法public String getType(){return "三角形";}public static void main(String[] args){Shape s = new Triangle("黑色",3,4,5);System.out.println(s.getType());System.out.println(s.calPerimeter());}}




0 0
原创粉丝点击