面向对象(中)
1.继承
extends可以继承属性和方法
优点①减少代码冗余,提高代码的复用性
②为之后多态的使用,提供了前提
继承的格式
class A extends B{}
A:子类、派生类 subclass
B:父类 超类 基类 superclass
private 也可以继承到
体现
一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。
特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。子类和父类的关系,不同于子集和集合的关系。
extends:延展、扩展
Java中继承的规定
- 一个类可以被多个子类继承。
- Java中类的单继承性:一个类只能有一个父类
- 子父类是相对的概念。
- 子类直接支持的父类,称为:直接父类。间接继承的父类
- 如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
所有的java类(除java.lang.object类之外)都直接或间接的继承于java.lang.object类 - 意味着,所有的java类具有java.lang.object类声明的功能。|
方法的重写(override / overwrite)
1.重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
2.应用:重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法。
3.重写的规定:
形参列表一样
方法的声明:权限修饰符返回值类型方法名(形参列表){
//方法体
}
约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
>特殊情况 父类的private权限的方法 子类重写不算重写(private的权限太少,看不到)不认为是一个重写
4.返回值类型
父类的重写的方法是void 子类也能是void
父类的重写方法是A类型 子类的重写的类型是A或者A的子类型
5.子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型(具体放到异常处理时候讲)
super关键词
super可以使用父类的属性或者方法
1.调用属性
super.xx 使用父类的属性
this.xx 使用子类的属性
如果子类的重写方法 想用父类就要用super
2.构造器的使用
super(形参列表) 表示使用父类的构造器
3.super的使用:调用属性和方法
3.1我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super . "
3.2特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
3.3特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
4.super调用构造器
4.1我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
4.2 super(形参列表)必须放在构造器的首行
4.3我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现
4.4在构造器的首行,没有显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器
4.5在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)",调用父类中的构造器
2.多态性
特点
对象的多态性:父类的引用指向子类的对象
Person p1 =new Man();
虚拟方法调用
只能调用父类的方法 不能调用子类的方法,但是运行的结果是子类的重写的结果
对象的多态性:只适用于方法,不适用于属性
例如p1.id 属性是父类的属性的id 不是子类的属性
虚拟方法
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
面试题
多态是编译性行为还是运行时行为
编译时才能知道是什么子类 这成为“动态绑定”
向下转型
调用子类的方法或者属性
因为new Man()已经把方法放在了堆里面 可以强转
Person p1 =new Man();
Man m=(Man) p1;
Women w1 =(Woman)p1; //会出现强转错误
instantceof关键词
a instanceof A //判断a是不是类A的实例 返回Boolean类型
if(p1 instanceof Man){
}
==和equals()区别
==:运算符
1.可以使用在基本数据类型变量和引用数据类型中
不同基本数据类型可以对比 除了Boolean
如果对比引用数据类型是比较地址是否相同
equals是方法
1.只能适用于引用数据类型
2.Object类中equals()的定义:
public boolean equals(Object o){
return (this== o);
}
像String、 Date、File、包装类等都重写了0bject类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
所以,我们自定义类要比较是否相等 ,要重写equals方法
@Override
//对比对象的属性是不是相同
public boolean equals(Object obj) {
if(this ==obj){
//地址相同直接返回true
return true;
}if ( obj instanceof 被对比的类 ) {
Customer o=(被对比的类)obj;//不转型的话属性用不了
return ojb.属性==对比.属性(基本数据类型) && 如果属性是引用数据类型则要equals
}
return false;
}
toString方法
1.当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
2 Object类中toString 的定义
3.像String、Date、File、包装类等都重写了0bject类中的toString()方法。使得在调用对象的toString()时,返回"实体内容"信息
自定义类 toString要自己重写
JUnit单元测试方法
步骤:
1.选中当前工程–右键选择:build path - add libraries - JUnit 4 -下一步2.创建Java类,进行单元测试。
此时的Java类要求:此类是public的 ②此类提供公共的无参的构造器3.此类中声明单元测试方法。
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入: import org.junit.Test;
5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
说明:
1.如果执行结果没有任何异常:绿条
2.如果执行结果出现异常:红条
也可以在类中直接@test 导入build就行
基本数据类型包装类String相互转换
//基本数据类型转换包装类
int i=1;
Integer in1 =new Integer(i);
//包装类转换成基本数据类型
Integer in2= new Integer(12);
int i2 =in2.intvalue();
//基本数据类型和包装类转换String
//方式一
int i1=1;
String s1 =i1+"";
//方式二 调用String.valueOf()
String s2 =String.valueOf(i1);
//String 转换基本数据类型 或者包装类
//调用包装类的 XX.parseXX(s1)
int num1 = Integer.parseInt(S1);
自动装箱 自动拆箱(jdk5 新特性)
//自动装箱 基本数据类型-》包装类
int num2=10;
Integer in1 =num2;
//自动拆箱 包装类-》基本数据类型
System.out.println(in1.toString())
int num3 =in1;
面试题
三元运算符要统一类型
public void test3(){
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); //false 引用数据类型对比地址
//Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[],保存了从-128~127范围的整数。如果我们使用自动装箱的方式,给Integer赋值的范围在-128~127范围内时,可以直接使用数组中的元素,不用再去new了
Integer m = 1;
Integer n = 1;
System.out.println(m == n); / /true
Integer x = 128; //相当于new Integer
Integer y = 128;
System.out.println(x == y);//false
}