OOP特征二:继承性
-
为什么要有继承?
- 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
-
此处的多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)。可以理解为:“子类 is a 父类”
-
类继承语法规则:class Subclass extends SuperClass{ }
-
继承的作用:
- 继承的出现减少了代码冗余,提高了代码的复用性。
- 继承的出现,更有利于功能的扩展。
- 继承的出现让类与类之间产生了关系,提供了多态的前提。
-
注意:不要仅为了获取其他类中某个功能而去继承
-
子类继承了父类,就继承了父类的方法和属性。
-
在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。
-
在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”。
-
关于继承的规则:
-
子类不能直接访问父类中私有的(private)的成员变量和方法
-
Java只支持单继承和多层继承,不允许多重继承
- 一个子类只能有一个父类
- 一个父类可以派生出多个子类
-
//举例
public class Person {
String name;
int age;
public void eat() {
System.out.println("吃饭");
}
}
public class Student extends Person{
int id;
public void say() {
System.out.println("读书");
}
}
public static void main(String[] args) {
Student student = new Student();
student.eat();
student.say();
}
//输出
吃饭
读书
方法的重写(override)
- 定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
- 要求:
- 子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
- 子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
- 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
- 子类不能重写父类中声明为private权限的方法
- 子类方法抛出的异常不能大于父类被重写方法的异常
- 注意:子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
//举例
public class Person {
String name;
int age;
public void eat() {
System.out.println("吃饭");
}
}
public class Student extends Person{
int id;
public void eat() {
System.out.println("学生吃饭");
}
public void say() {
System.out.println("读书");
}
}
public static void main(String[] args) {
Student student = new Student();
student.eat();
student.say();
Person person = new Person();
person.eat();
}
//输出
学生吃饭
读书
吃饭
四种访问权限修饰符
- Java权限修饰符public、protected、(缺省)、private置于类的成员定义前,用来限定对象对该类成员的访问权限。
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
---|---|---|---|---|
private | YES | |||
default(缺省) | YES | YES | ||
protectd | YES | YES | YES | |
public | YES | YES | YES | YES |
- 对于class的权限修饰只可以用public和default(缺省)。
- public类可以在任何对方被访问
- default类之可以被同一个包内部的类访问
关键字super
-
在Java类中使用super来调用父类中的指定操作:
- super可用于访问父类中定义的属性
- super可用于调用父类中定义的成员方法
- super可用于在子类构造器中调用父类的构造器
-
注意:
- 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
- super的追溯不仅限于直接父类
- super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
-
调用父类的构造器时:
- 子类中所有的构造器默认都会访问父类中空参数的构造器
- 当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器。同时,只能”二选一”,且必须放在构造器的首行
- 如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错
-
this和super的区别
区别点 this super 访问属性 访问本类中的属性,如果本类没有此属性则从父类中继续查找 直接访问父类中的属性 调用方法 访问本类中的方法,如果本类没有此方法则从父类中继续查找 直接访问父类中的方法 调用构造器 调用本类构造器,必须放在构造器的首行 调用父类构造器,必须放在子类构造器的首行 public class Person { String name; int age; public Person() { System.out.println("创建一个人"); } public void eat() { System.out.println("吃饭"); } } public class Student extends Person{ int id; public Student(){ //super() 首行隐藏了super() System.out.println("创建一个学生"); } public void eat() { System.out.println("学生吃饭"); super.eat(); } public void say() { System.out.println("读书"); } } public static void main(String[] args) { Student student = new Student(); student.eat(); student.say(); } //输出 创建一个人 创建一个学生 学生吃饭 吃饭 读书
OOP特征三:多态性
-
多态性,是面向对象中最重要的概念,在Java中的体现:
- 对象的多态性:父类的引用指向子类的对象
- 可以直接应用在抽象类和接口上
-
Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。
- 简称:编译时,看左边;运行时,看右边。
- 若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)
- 多态情况下,“看左边”:看的是父类的引用(父类中不具备子类特有的方法)
- “看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)
-
对象的多态 —在Java中,子类的对象可以替代父类的对象使用
- 一个变量只能有一种确定的数据类型
- 一个引用类型变量可能指向(引用)多种不同类型的对象
-
子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型(upcasting)。
-
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student(); m.school = “pku”; //合法,Student类有school成员变量 Person e = new Student(); e.school = “pku”; //非法,Person类没有school成员变量
- 属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误
-
虚拟方法调用(多态情况下)
- 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
Person e = new Student(); e.getInfo(); //调用Student类的getInfo()方法
- 编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类 的getInfo()方法。——动态绑定
-
从编译和运行的角度看
- 重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;
- 而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。
- 引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”
-
多态作用:提高了代码的通用性,常称作接口重用
-
前提:需要存在继承或者实现关系。有方法的重写
-
成员方法:
- 编译时:要查看引用变量所声明的类中是否有所调用的方法。
- 运行时:调用实际new的对象所属的类中的重写方法。
-
成员变量:不具备多态性,只看引用变量所声明的类
-
子类继承父类
- 若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中。
- 对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量
instanceof操作符
- x instanceof A:检验x是否为类A的对象,返回值为boolean型。
- 要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
- 如果x属于类A的子类B,x instanceof A值也为true
对象类型转换(Casting)
- 基本数据类型的Casting:
- 自动类型转换:小的数据类型可以自动转换成大的数据类型
- 强制类型转换:可以把大的数据类型强制转换(casting)成小的数据类型
- 对Java对象的强制类型转换称为造型
- 从子类到父类的类型转换可以自动进行
- 从父类到子类的类型转换必须通过造型(强制类型转换)实现
- 无继承关系的引用类型间的转换是非法的
- 在造型前可以使用instanceof操作符测试一个对象的类型
Object类的使用
- Object类是所有Java类的根父类
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类 为java.lang.Object类
方法名称 | 类型 | 描述 |
---|---|---|
public Object() | 构造 | 构造器 |
public boolean equals(Object obj) | 普通 | 对象比较 |
public int hashCode() | 普通 | 取得Hash码 |
public String toString() | 普通 | 对象打印时调用 |
-
==操作符与equals方法
- ==
- 基本类型比较值:只要两个变量的值相等,即为true。
- 引用类型比较引用(是否指向同一个对象):只有指向同一个对象时,==才返回true。
- 用“==”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),否则编译出错
- equals
- 所有类都继承了Object,也就获得了equals()方法。还可以重写。
- 只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象。
- 格式:obj1.equals(obj2)
- 特例:当用equals()方法进行比较时,对类File、String、Date及包装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象.
- 原因:在这些类中重写了Object类的equals()方法。
- 当自定义使用equals()时,可以重写。用于比较两个对象的“内容”是否都相等
- ==
-
重写equals()方法的原则
- 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
- 自反性:x.equals(x)必须返回是“true”。
- 传递性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
- 一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
- 任何情况下,x.equals(null),永远返回是“false”; x.equals(和x不同类型的对象)永远返回是“false”。
-
toString方法
- toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
- 在进行String与其它类型数据的连接操作时,自动调用toString()方法
Date now=new Date(); System.out.println(“now=”+now); 相当于 System.out.println(“now=”+now.toString());
- 可以根据需要在用户自定义类型中重写toString()方法
如String 类重写了toString()方法,返回字符串的值。 s1=“hello”; System.out.println(s1);//相当于System.out.println(s1.toString());
- 基本类型数据转换为String类型时,调用了对应包装类的toString()方法
int a=10; System.out.println(“a=”+a);
JUnit单元测试步骤(Eclipse版)
- 选中当前工程-右键选择-点击build path-点击add libraries-选中JUnit 4-下一步
- 创建Java类,进行单元测试。
- 此时的Java类要求:①此类是public的,②此类有公共的无参构造器
- 测试方法的格式:方法的权限是public的,没有返回值,方法名自定义
- 此单元测试方法上需要声明注解:@Test,并在单元测试类中导入对应包:
- 声明好单元测试方法以后,就可以在方法体内测试相关的代码
- 写完代码以后,左键双击单元测试方法名,右键-run as-JUnit Test
- 说明:如果执行结果没有任何异常,则显示为绿条。如果执行结果出现异常,则显示红条
包装类的使用
- 针对八种基本数据类型定义相应的引用类型—包装类(封装类)
- 有了类的特点,就可以调用类中的方法,Java才是真正的面向对象
-
基本数据类型包装成包装类的实例 ---装箱
- 通过包装类的构造器实现:
//基本数据类型转换成包装类:调用包装类的构造器 int num = 10; Integer in1 = new Integer(num); System.out.println(in1);//10
- 还可以通过字符串参数构造包装类对象:
//基本数据类型转换成包装类:通过字符串参数构造包装类对象 Integer in2 = new Integer("123"); System.out.println(in2);//123 //下面两行会报异常 //Integer in3 = new Integer("123asd"); //System.out.println(in3); //特殊情况:与其他类型相比,这个不会报异常 Boolean bool = new Boolean("true123"); System.out.println(bool);//false
- 自动封箱(JDK5.0以后支持),但类型必须匹配。
//基本数据类型转换成包装类:自动封箱(JDK5.0以后支持) int a = 10; Integer in = a; System.out.println(in);//10
-
获得包装类对象中包装的基本类型变量 ---拆箱
- 调用包装类的.xxxValue()方法:
//包装类转换成基本数据类型:调用包装类的xxxValue()方法 Integer in = new Integer("123"); int a = in.intValue(); System.out.println(a);//123
- 自动拆箱(JDK5.0以后支持),但类型必须匹配。
//包装类转换成基本数据类型:自动拆箱(JDK5.0以后支持) Integer in = new Integer("123"); int a = in; System.out.println(a);//123
-
字符串转换成基本数据类型
- 通过包装类的构造器实现:
- 通过包装类的parseXxx(String s)静态方法:
//String类型转换成基本数据类型,包装类: //1.调用包装类的parseXxx(String s)方法 String str1 = "123"; int num1 = Integer.parseInt(str1); System.out.println(num1);//123 //报NumberFormatException异常 //String str4 = "123a"; //int num2 = Integer.parseInt(str4); //System.out.println(num2);//123 String str2 = "true"; boolean boo1 = Boolean.parseBoolean(str2); System.out.println(boo1);//true //特殊情况:不会报异常 String str3 = "true1"; boolean boo2 = Boolean.parseBoolean(str3); System.out.println(boo2);//false //2.调用包装类的构造器 String str5 = "12"; int num3 = new Integer(str5); System.out.println(num3);//12
-
基本数据类型转换成字符串
- 调用字符串重载的valueOf()方法:
- 更直接的方式:连接运算
//基本数据类型,包装类转换成String类型 //1.连接运算 String str1 = 10 + ""; System.out.println(str1);//10 //2.调用String的valueOf(Object,object或基本数据类型)方法 int i = 10; String str2 = String.valueOf(i); System.out.println(str2);//10 Double d = new Double(12.4); String str3 = String.valueOf(d); System.out.println(str3);//12.4
-
装箱:包装类使得一个基本数据类型的数据变成了类。有了类的特点,可以调用类中的方法。
-
拆箱:将数字包装类中内容变为基本数据类型
-
包装类在实际开发中用的最多的在于字符串变为基本数据类型
-
Integer的补充
//Integer内部定义了静态的IntegerCache结构,IntegerCache中定义了一个Integer[], //数组静态保存了从-128~127范围的数。如果我们使用自动装箱的方式,给Integer赋值的范围在 //-128~127之间,可以直接使用数组中的元素,不用再去new了。 Integer a = 1; Integer b = 1; System.out.println(a);//1 System.out.println(b);//1 System.out.println(a == b);//true Integer in1 = 128; Integer in2 = 128; System.out.println(in1);//128 System.out.println(in2);//128 System.out.println(in1 == in2);//false
总结
/**
* 1.面向对象的特征之二
* 一,继承性的好处
* ①减少了代码的冗余,提高了代码的复用性
* ②便于功能的扩展
* ③为多态性的使用,提供了前提
* 二,继承的格式:class A extends B{}
* A:子类,派生类,subclass
* B:父类,超类,基类,superclass
* extends:延展,扩展
* 2.1体现:一旦子类A继承了父类B以后,子类A中就获取了父类B中声明的所有属性和方法。
* 特别的,父类中声明为private的属性和方法,子类继承父类后,仍然认为获取了父类中私有的结构。
* 只是因为封装性的影响,使得子类不能直接调用父类的结构而已
* 2.2子类继承父类以后,还可以声明自己特有的属性和方法:实现功能的扩展
* 子类和父类的关系,不同于子集和集合的关系
* 三,Java中关于继承的规定
* ①一个类可以被多个子类继承
* ②Java中类的单继承性:一个类只能有一个父类
* ③子负类是相对的概念
* ④子类直接继承的父类称为:直接父类。间接继承的父类称为:间接父类
* ⑤子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
* 四,如果我们没有显示的定义一个类的父类的话,则此类继承于java.lang.Object类
* 所有的java类(除java.lang.Object类)都直接或间接的继承于java.lang.Object
* 所以所有的java类具有java.lang.Object类声明的功能
* 2.方法的重写(override)
* 一,重写:子类继承父类以后,可以对父类中同名参数的方法进行覆盖操作
* 二,应用:重写以后,当创建子类对象以后,通过子类对象调用父类中的同名同参数的方法时,
* 实际执行的是子类重写父类的方法
* 三,重写的规定:
* 方法的声明:权限修饰符 返回值类型 方法名(形参列表){
* //方法体
* }
* 约定俗称:
* ①子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和参数列表形同
* ②子类重写的方法的权限修饰符不小于父类被重写的 方法的权限修饰符
* >特殊情况:子类不能重写父类中声明为private权限的方法
* ③返回值类型
* >父类被重写的方法的返回值类型是void,则子类重写的方法的返回值只能是void
* >父类被重写的方法的返回值类型是A类型(引用类型),则子类重写的方法的返回值可以是A类型的或A类的子类
* >父类被重写的方法的返回值类型是基本数据类型,则子类重写的方法的返回值只能也是对应的基本类型
* ④子类重写的方法抛出的异常类型不大于父类被重写的方法排除的异常类型
* ⑤子类和父类中同名同参数的方法要么都声明为非static的(可以重写),要么都声明为static的(不是重写)
* 3.super关键字的使用
* 一,super理解为:父类的
* 二,super可以用来调用:属性,方法,构造器
* 三,super调用属性或方法:
* ①我们可以在子类的方法或构造器中,通过使用“super.属性”或“super.方法”的方式,显示的调用
* 父类中声明的属性或方法。但是通常情况下我们都习惯省略“super.”
* ②特殊情况:当子类和父类中定义了同名的属性时,我们想要在子类中调用父类中声明的属性,则必须显示的使用
* “super.属性”的方式,表明调用的是父类中声明的属性。
* ③特殊情况:当子类重写了父类的方法以后,外卖想在子类的方法中调用父类中被重写的方法时,必须显示的使用
* “super.方法”的方式,表明调用的是父类中被重写的方法。
* 四,super调用构造器:
* ①我们可以在子类的构造器中显式的使用“super(形参列表)”的方式,调用父类中声明的制定的构造器
* ②“super(形参列表)”的使用,必须声明在子类构造器的首行
* ③我们在类的构造器中,针对“this(形参列表)”或“super(形参列表)”只能二选一,不能同时出现
* ④在构造器的首行没有显示的声明“this(形参列表)”或“super(形参列表)”,则默认使用“super()”调用父类中空参的构造器
* ⑤在类的多个构造器中,至少有一个类的构造器中使用了“super(形参列表)”,调用父类中的构造器
* 4.子类对象实例化的过程
* 一,从结果上看:(继承性)
* 子类继承父类后,就获取了父类中声明的属性或方法
* 创建子类的对象,在堆空间中,就会加载所有父类中的声明的属性
* 二,从过程上看:
* 当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器
* 直到调用了java.lang.Obkect类中空参的构造器为止,正因为加载了所有的父类的结构,所以才可以看到内存中有父类中
* 的结构,子类对象才可以调用父类的结构
* 明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建了一个对象,即为new的子类对象
* 5.多态性的理解
* 一,理解多态性:可以理解为一个事务的多种形态
* 二,何为多态性
* 对象多态性:父类的引用指向子类的对象(或子类的对象赋给对象的引用)
* 三,多态的使用:虚拟方法调用
* 有了对象的多态性后,我们在编译时期,只能调用父类中声明的方法,但在运行时期,我们实际调用的是父类中重写子类的方法
* 举例。我们定义了一个A类,定义了一个B类,且B类继承A类。在A类中定义一个输出方法输出a。B类中重写这个输出方法输出b。
* 另外B类中在定义一个show()方法,输出show。
* 当执行A a = new B(); a.printf(); 此时的输出是B类中重写的内容。即输出b
* 但当编写a.show()时会编译不通过。
* 总结:编译看左边,运行看右边。
* 四,多态性的使用前提:
* ①类有继承关系。②方法要重写。
* 五,多态性的好处:
* ①在调用以对象为参数的方法时,将方法的参数设置为父类,那么当传进去不同子类的对象时,执行的结果也就不同。
* 如果此时没有多态性。我们必须将这个方法重写很多次以适应子类的不同。因此多态性可以减少代码的编写
* 六,多态性的注意点:
* ①对象多态性只适用于方法,不适用于属性(属性和方法都看左边)
* 七,内存中的变化。
* 多态性的使用时,内存中实际上是加载了子类特有的属性何方法的。但是由于变量被声明为父类类型,导致编译时,
* 只能调用父类中声明的属性何方法。子类特有的属性仍然存在在内存中但无法调用
* 6.instanceof关键字
* 一,多态性使用后如何让变量调用子类特有的属性和方法?
* ①向下转型,使用强制类型转换符
* 缺点:A类是B类和C类的父类。当A a = new B();时,强转a为C类时会出现ClassCastException异常
* ②使用instanceof关键字提前判断是否可以强转
* 二,使用:a instanceof A:表示判断对象a是否是类A的实例。如果是返回true。如果不是返回false
* 三,使用情景:为了避免在向下转型时出现ClassCastException异常,我们在向下转型之前,先进行instanceof的判断
* ,一旦返回true就进行向下转型。如果返回false则不能进行向下转型
* 四,补充:B类是A类的父类的话那么a instanceof A返回true,且a instanceof B也返回true.
* 7.Object类
* ①:Object类是所有Java类的根父类
* ②:如果在类的声明中未使用extends关键字指明其父类。则默认父类为java.lang.Object类
* ③:Object类中的功能(属性,方法)具有通用性。
* 属性:无
* 方法:equals()/toStrings()/getClass()/hasCode()/clone()/finalize()/wait()/notify()/notifyAll()
* ④:Object类只声明了一个空参的构造器
* 一,==和equals()的区别
* ==的使用:
* ①:可以使用在基本数据类型和引用数据类型变量中
* ②:如果比较的是基本数据类型变量,比较两个变量的数据是否相等。(不一定类型相同)
* ③:如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
* ④:==符号在使用时要保证符号两边的数据类型要一致。既可以比较
* equals()的使用
* ①:是一个方法,而非运算符
* ②:只能适用于引用数据类型
* ③:Object类中的equals()中对定义:和==是相同的,都是比较两个对象的地址值是否相同
* 源码:public boolean equals(Object obj) {
* return (this == obj);
* }
* ④:像String,Date,File,包装类等都重写了Object类中的equals()方法,重写后比较的是两个对象的“实体内容”是否相同
* 而不是引用的地址是否相同
* ⑤: 自定义类的比较需要我们重写equals()方法。一般情况下我们会选择自动生成的equals()方法。而不自己写。
* 二,toString()方法的使用
* ①:Object类的toString()方法输出的是对象的引用地址值
* ②:当我们输出一个对象的应用时,实际上是调用对象的toString()方法
* ③:像String,Date,File,包装类等都重写了Object类中的toString()方法。
* 使得在调用上述类型的对象的toString()方法时,返回的是对象的“实体内容”信息
* ④:自定义的类可以重写toString()方法。重写此方法一般使用自动生成,重写后的方法返回的是实体内容的信息
* 8.包装类的使用
* ①:Java提供了8中基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
* ②:基本数据类型,包装类,String三者之间的转换
* 一,基本数据类型转换成包装类
* ①:调用包装类的构造
* ②:自送封箱(JDK5.0以后支持)
* 二,包装类转换成基本数据类型
* ①:调用包装类的xxxValue()方法
* ②:自动拆箱(JDK5.0以后支持)
* 三,基本数据类型,包装类转换成String类型
* ①:连接运算
* ②:调用String的valueOf(Object,object或基本数据类型)方法
* 四,String类型转换成基本数据类型,包装类
* ①:调用包装类的parseXxx(String s)方法
* ②:调用包装类的构造器
*/