Java 类的一些高级特征
1. 面向对象的特征二:继承性
* 1.为什么要设计继承性?
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
* 2.通过"class A extends B"类实现类的继承。
子类:A 父类(或基类 SuperClass):B
* 3.子类继承父类以后,父类中声明的属性、方法,子类就可以获取到。
明确:当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接 调用罢了。
子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分。
extends:子类是对父类功能的“扩展”,明确子类不是父类的子集。
*4. java中类的继承性只支持单继承:一个类只能继承一个父类。反之,一个父类可以有多个子类。
2、方法的重写、覆盖
1.前提:有子类继承父类
2.子类继承父类以后,若父类的方法对子类不适用,那么子类可以对父类的方法重写(override overwrite)、覆盖、覆写。
3.重写的规则: 1)要求子类方法的“返回值类型 方法名 (参数列表)”与父类的方法一样
2)子类方法的修饰符不能小于父类方法的修饰符
3)若父类方法抛异常,那么子类方法抛的异常类型不能大于父类的。
4)子父类的方法必须同为static或同为非static的。
练习:
如果现在父类的一个方法定义成private访问权限,在子类中将此方法声明为default访问权限,那么这样还叫重写吗?(NO)
3. super 关键字
super:可以用来修饰属性、方法、构造器
1)当子类与父类中有同名的属性时,可以通过"super.此属性"显式的调用父类中声明的属性.
若想调用子类的同名的属性使用 “this.此属性”
2)当子类重写父类的方法以后,在子类中若想再显式的调用父类的被重写的方法,就需要使用“super.方法”
3)super修饰构造器:通过在子类中使用“super(形参列表)”来显式的调用父类中指定的构造器。
>在构造器内部,“super(形参列表)”必须要声明在首行!
>在构造器内部,“this(形参列表)”或“super(形参列表)”只能出现一个!
>当构造器中,不显式的调用“this(形参列表)”或“super(形参列表)”其中任何一个,默认调用的是父类空参的构造器!
建议:设计一个类时,尽量要提供一个空参的构造器!
this 和 super 的区别:
4. 子类对象的实例化过程
子类对象实例化时,是拥有父类所有属性和方法的,只是有访问权限的问题。
思考:
1).为什么super(…)和this(…)调用语句不能同时在一个构造器中出现?
2).为什么super(…)或this(…)调用语句只能作为构造器中的第一句出现?
练习:(下面代码执行结果)
class Creature{ public Creature(){ System.out.println("Creature无参数的构造器"); } } class Animal extends Creature{ public Animal(String name){ System.out.println("Animal带一个参数的构造器,该动物的name为" + name); } public Animal(String name , int age){ this(name); System.out.println("Animal带两个参数的构造器,其age为" + age); } } public class Wolf extends Animal{ public Wolf(){ super("灰太狼", 3); System.out.println("Wolf无参数的构造器"); } public static void main(String[] args){ new Wolf(); } }
5. 面向对象的特征三:多态性
1.多态性指的是什么?多态性,可以理解为一个事物的多种表型形态。
1)方法的重载与重写 2)子类对象的多态性
// 子类对象的多态性:父类的引用指向子类对象
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = new Student();
e.school = “pku”; //非法,Person类没有school成员变量
// 虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法 (动态绑定)
2.子类对象的多态性使用的前提:①要有类的继承②要有子类对父类方法的重写
3.程序运行分为编译状态和运行状态。
对于多态性来说,编译时,"看左边",将此引用变量理解为父类的类型
运行时,"看右边",关注于真正对象的实体:子类的对象。那么执行的方法就是子类重写的。
4.子类对象的多态性,并不使用于属性。
5.子类继承父类, 成员变量和方法的区别
若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中
对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量
6. instanceof 操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
6. 对象类型转换 (Casting )
1. 基本数据类型的Casting:
(1) 自动类型转换:小的数据类型可以自动转换成大的数据类型
如long g=20; double d=12.0f
(2) 强制类型转换:可以把大的数据类型强制转换(casting)成小的数据类型
如 float f=(float)12.0; int a=(int)1200L
2. 对Java对象的强制类型转换称为造型
从子类到父类的类型转换可以自动进行
从父类到子类的类型转换必须通过造型(强制类型转换)实现
无继承关系的引用类型间的转换是非法的
在造型前可以使用instanceof操作符测试一个对象的类型
7.Object 类
Object类是所有Java类的根父类
如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类
1. ==操作符与equals方法
==
1.基本数据类型:根据基本数据类型的值判断是否相等。相等返回true,反之返回false
// 注:两端数据类型可以不同,在不同的情况下,也可以返回true。
2.引用数据类型:比较引用类型变量的地址值是否相等。
equals():
①只能处理引用类型变量 ②在Object类,equals()仍然比较的两个引用变量的地址值是否相等
像String 包装类 File类 Date类这些重写Object类的equals()方法,比较是两个对象的"实体内容"是否完全相同。
2. toString() 方法
(1) toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
(2) 在进行String与其它类型数据的连接操作时,自动调用toString()方法
(3) 可以根据需要在用户自定义类型中重写toString()方法
(4) 基本类型数据转换为String类型时,调用了对应包装类的toString()方法
(5) 像 String 类、包装类、File 类、Date 类等,已经实现了 Object 类中 toString() 方法的重写。
8. Junit单元测试类
* 1.当前工程下-右键build path-add libraries-Junit4
* 2.在主类中,创建一个空参的无返回值的方法,(如:public void test1())用于代码的测试,方法上声明:@Test
* 3.导入import org.junit.Test;
* 4.在test1()方法中,进行代码的编写。
* 5.测试:双击方法名,右键run as-junit Test即可。
9. 包装类(Wrapper)
针对八种基本定义相应的引用类型—包装类(封装类). 有了类的特点,就可以调用类中的方法。
(1) 基本数据类型包装成包装类的实例 ---装箱
通过包装类的构造器实现:
int i = 500; Integer t = new Integer(i);
还可以通过字符串参数构造包装类对象:
Float f = new Float(“4.56”);
Long l = new Long(“asdf”); //NumberFormatException
//对于Boolean 来讲,当形参是"true"时,返回true, 除此之外,都是false.
(2) 获得包装类对象中包装的基本类型变量 ---拆箱
调用包装类的.xxxValue()方法:
boolean b = bObj.booleanValue();
(3) JDK1.5之后,支持自动装箱,自动拆箱。但类型必须匹配。
Integer i3 = i4;//自动装箱 Boolean bb = false; int i5 = i3;//自动拆箱
(4) 字符串转换成基本数据类型
通过包装类的构造器实现:
int i = new Integer(“12”);
通过包装类的parseXxx(String s)静态方法:
Float f = Float.parseFloat(“12.1”);
(5) 基本数据类型转换成字符串
调用字符串重载的valueOf()方法:
String fstr = String.valueOf(2.34f);
更直接的方式:
String intStr = 5 + “”