一、基本类型的包装类
1.引出基本类型的包装类
问题1:在面向对象中,”一切皆对象”,现在问题来了,int age = 17;请问这age代码哪里有对象,基本类型变量,不是对象.此时有矛盾.
问题2:现在给你一个复杂的十进制数据,请你迅速在程序给我转换为2进制,8进制,16进制,算法太麻烦了.
-------------------------------------------------------------------------
上述的问题,进就是因为基本数据类型缺少对象,如果需要对象,必须先有类.
2.装箱与拆箱
自动装箱和拆箱,也是一个语法糖/编译器级别新特性.
在底层依然是手动装箱和拆箱操作.
Object可以接受一切数据类型的值.
Object数组:Object[]该数组可以装一切数据类型.
3.包装类的常用操作方法:
装箱:
Integer i1 = new Integer(123);// 1) 通过构造器装箱
Integer i2 =Integer.valueOf(123);// 2)通过静态方法valueOf()装箱,推荐,带有缓存,可节省内存空间。
拆箱:
a.把String转换为包装类类型:
方式1: static Xxx valueOf(String str) :把String转换为包装类的对象
Integeri1 = Integer.valueOf(“123”);
方式2:new Xxx(String str):
Integer i2= new Integer(“123”);
b.把包装类对象转换为String.
String str = 任何对象.toString();
c.把基本数据类型转换为String:
String str = 17 + ””;
d. 把String转换为基本数据类型:
static xxx parseXxx(String s) :xxx表示8大基本数据类型
int num = Integer.parseInt(input);
5)Booleanb = new Boolean("SB");//false
4.包装类中的缓存设计(享元设计),本质就是缓存设计:
Byte、Short、Integer、Long:缓存[-128,127]区间的数据;
//演示包装类中的享元设计
class FlyweightDemo
{
public static void main(String[] args)
{
Integer num1 = new Integer(12);
Integer num2 = new Integer(12);
System.out.println(num1 == num2); //false,另开辟堆空间,引用地址不同
System.out.println(num1.equals(num2));//true,eqauls()方法仅比较值
Integer num3 = Integer.valueOf(12);
Integer num4 = Integer.valueOf(12);
System.out.println(num3 == num4); //true,在缓存方位内,直接调用缓存中的值
System.out.println(num3.equals(num4));//true,eqauls()方法仅比较值
Integer num31 = Integer.valueOf(1211);
Integer num41 = Integer.valueOf(1211);
System.out.println(num31 == num41);//false,超过缓存方位,需另开辟空间
System.out.println(num31.equals(num41));//true,eqauls()方法仅比较值
}
}
5.Integer与int的区别(包装类型和基本数据类型的区别)
1):默认值:
int的默认值是0.
Integer的默认值为null.
推论:Integer既可以表示null,又可以表示0.
2):包装类中提供了该类型相关的很多算法操作方法.
static String toBinaryString(int i) :把十进制转换为二进制
staticString toOctalString(int i) : :把十进制转换为八进制
static String toHexString(int i) : :把十进制转换为十六进制
3):在集合框架中,只能存储对象类型,不能存储基本数据类型值.
4):请问:Integer和int是相同的数据类型吗?不是:
public void doWork(int val){}
public void doWork(Integer val){}
/*在同类中,共存,方法重写,参数列表不同,int与Integer不是相同类型*/
二、抽象方法与抽象类
1.引入抽象概念
//案例:求圆(circle)、矩形(rectangle)、三角形(Triangle )的面积
class Graph
{
public Double getArea()
{
return 0.0;
}
}
//圆
class Circle extends Graph
{
private Integer r;
Circle(Integer r)
{
this.r = r;
}
public Double getArea()
{
return 3.14 * r * r;
}
}
//矩形
class Rectangle extends Graph
{
private Integer width;
private Integer height;
Rectangle(Integer width, Integer height)
{
this.width = width;
this.height = height;
}
public Double getArea()
{
return width.doubleValue() *height.doubleValue();
}
}
//三角形
class Triangle extends Graph
{
private Integer a;
private Integer b;
private Integer c;
Triangle(Integer a, Integer b, Integer c)
{
this.a = a;
this.b = b;
this.c = c;
}
public Double getArea()
{
Double p = (a + b +c) / 2.0;
return Math.sqrt(p * ( p - a ) * ( p - b ) * ( p - c ));
}
}
class AbstractDemo
{
public static void main(String[] args)
{
System.out.println(new Circle(10).getArea());
System.out.println(new Rectangle(10,5).getArea());
System.out.println(new Triangle(3,4,5).getArea());
}
}
上述设计的问题:
1):每一个图形都有面积,所在在Graph类中定义求面积的方法getArea没问题. 但是, 不同的具体图形求面积的算法是不一样的,也就是说,每一个图形的子类都必须去覆盖getArea方法,如果不覆盖,应该语法报错,必须覆盖.
2.抽象方法
3.抽象类
① 不能创建实例即不能new一个抽象类,即使创建出抽象类对象,调用抽象方法,根本没有方法体。
② 可以不包含抽象方法,若一旦包含,该类必须作为抽象类,抽象类可以包含普通方法(留给子类调用的),抽象类是有构造器的,子类构造器必须先调用父类构造器。
③ 若子类没有实现/覆盖父类所有的抽象方法,那么子类也得作为抽象类(抽象派生类)。
④ 构造方法不能都定义成私有的,否则不能有子类(创建子类对象前先调用父类构造方法)。
⑤ 抽象类不能使用final修饰,因为必须有子类,抽象方法才能得以实现。
⑥ 是不完整的类,需作为父类(必须要有子类),功能才能得以实现。
抽象类:一般的,我们起名,习惯使用Abstract作为前缀,让调用者一看就知道是抽象类.
//案例:求圆(circle)、矩形(rectangle)、三角形(Triangle )的面积
abstract class Graph
{
abstract public Double getArea();//没方法体,子类中必须覆盖
}
//圆
class Circle extends Graph
{
private Integer r;
Circle(Integer r)
{
this.r = r;
}
public Double getArea()
{
return 3.14 * r * r;
}
}
//矩形
class Rectangle extends Graph
{
private Integer width;
private Integer height;
Rectangle(Integer width, Integer height)
{
this.width = width;
this.height = height;
}
public Double getArea()
{
return width.doubleValue() *height.doubleValue();
}
}
//三角形
class Triangle extends Graph
{
private Integer a;
private Integer b;
private Integer c;
Triangle(Integer a, Integer b, Integer c)
{
this.a = a;
this.b = b;
this.c = c;
}
public Double getArea()
{
Double p = (a + b +c) / 2.0;
return Math.sqrt(p * ( p - a ) * ( p - b ) * ( p - c ));
}
}
class AbstractDemo
{
public static void main(String[] args)
{
System.out.println(new Circle(10).getArea());
System.out.println(new Rectangle(10,5).getArea());
System.out.println(new Triangle(3,4,5).getArea());
}
}
三、模板方法设计模式
模板方法设计模式:在父类的一个方法中定义一个总体算法的骨架(模板方法),而将某一些一些步骤延迟到子类中,因为不同的子类实现细节不同。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
-------------------------------------------------------------------------------------------------------------
抽象父类负责定义操作中的业务骨架,而把某些具体的实现步骤延迟到子类中去实现。
抽象父类至少提供的方法:
1)模板方法:一种通用的处理方式,即模板(总体算法的骨架);
2)抽象方法:一种具体的业务功能实现,由子类完成;
注意:抽象父类提供的模版方法只是定义了一个通用算法,其实现必须依赖子类的辅助。