1.OPP特征二:继承性
1.继承性的好处:
①减少了代码的冗余,提高了代码的复用率
②便于功能的扩展
③为之后多态性的使用,提供了前提
2.继承性的格式
class A extends B
A:子类、派生类、subclass
B:父类、基类、superclass
体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的结构、属性、方法
特别的:父类中声明为private的属性或方法、子类继承父类后,仍然认为获取了父类中私有的结构
只因有封装性的影响,使得子类不能直接调用父类的结构而已
子类继承父类后、还可以声明自己特有的属性或方法,实现功能的拓展
注:①一个类可以被多个子类继承
②Java中类的单继承性:一个类只允许有一个父类(接口可以多继承)
③类可以多层继承
④子类继承父类以后、获取了直接父类、以及所有间接父类声明中的属性和方法
3.java.lang.Object类
3.1如果我们没有现实的声明一个类的父亲的话,则此类继承java.lang.Object类
3.2所有的Java类(除java.lang.Object类)都直接或间接继承于java.lang.Object类
2.方法的重写override/overwrite
1.定义:子类继承父类后,可以对父类同名同参数的方法,进行重写
2.应用:重写后,当创建子类对象以后,通过子类对象调用子父类中同名同参的方法时,实际执行的时子类重写父类的方法。
3.重写的规定:
方法的声明:权限修饰符 返回值类型 方法名(形参列表)throw 异常的类型{
//方法体
}
约定俗成:子类中的叫重写的方法、父类中的叫被重写的方法
①子类重写的方法的方法名和形参列表与父类相同
②子类重写的方法的权限修饰符不小于父类被重写的权限修饰符
>特殊情况:子类不能重写父类中声明为private的
③返回值类型:
>父类被重写的方法的返回值类型时void,则子类重写的方法的返回值类型只能是void
>父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值可以是A类或A类的子类(子类即是包括A类的类)
>父类被重写的方法的返回值类型是基本数据类型(例:double),则子类重写的方法的返回值类型是相同的基本数据类型(也是double)
④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
子类和父类中同名同参数的方法,要么都声明为非static的(考虑重写),或者static的(不是重写)
3.四种访问权限修饰符
4.关键字:super
1.super:父类的…
2.super可以用来调用:属性、方法、构造器
3.super的使用
System.out.println("id="+id);
System.out.println("id="+super.id);
①我们可以在子类的方法或构造器中,通过使用super.方法/属性的方式,调用父类中声明的属性或方法。通常情况下,省略super.
②特殊情况:当子类和父类定义了同名的属性时,想在子类中调用父类中声明的属性或方法,则必须显式的使用super.方法/属性
4.super调用构造器:
①在子类的构造器中显示的使用super(形参列表),调用父类中生命的值定的构造器
②super(形参列表)的使用,必须声明在子类构造器的首行
③在类的构造器中针对于this(形参列表)、super(形参列表)只能二选一,不能同时出现
④在构造器的首行,没有this、super,则默认调用的是父类中空参的构造器即super()
⑤在类的多个构造器中,至少有一个类的构造器中使用了super(形参列表)调用父类中的构造器
5.子类对象的实例化过程
1.从结果上看:
子类继承父类以后,就获取父类中声明的属性或方法
创建子类的对象,在堆空间中,就会加载所有父类中生命的属性
2.从结果上看:
当我们通过子类的构造器创建子类对象时,一定会直接或间接调用其父类的构造器,进而调用父类的父类构造器…直到调用了Java.lang.Object类中空参的构造器为止。正因为加载过所有父类的结构,所以才可以看到内存中有父类的结构,子类对象才可以考虑进行调用。
明确:虽然创建子类对象时,调用了父类构造器,但是自始至终就创建过一个对象即为new的对象。
6.多态性(编译看左,运行看右)
理解:一个事物得多种形态
何为多态性:
对象的多态性:父类的引用指向子类的对象(子类对象赋给父类的引用);
多态的使用:当调用子父类同名同参的方法时,实际执行的是子类重写的方法(虚拟方法使用)
有了对象的多态性以后,编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
多态性使用的前提:①类的继承关系
②方法的重写
对象的多态性:只适用于方法
不适用于属性
public class AniamlTest {
public static void main(String[] args) {
AniamlTest test =new AniamlTest();
test.ibao(new Dog());
test.ibao(new Cat());
}
public void ibao(Animal animal){
animal.eat();
animal.shout();
}
}
class Animal{
public void eat(){
System.out.println("chi");
}
public void shout(){
System.out.println("jiao");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void shout() {
System.out.println("汪汪汪");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void shout() {
System.out.println("喵喵喵");
}
}
7.重载和多态
重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰,对于编译器而言,这些同名方法就成了不同的方法。他们的调用地址在编译期间就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。
而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”
Bruce Eckel :不要犯傻,如果它不是晚绑定,它就不是多态。
重载不表现多态,重写表现多态
8.关键字:instanceof
有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类中特有的属性和方法不能调用。
如何才能使用子类特有的属性和方法呢?
向下转型:使用强制类型转换(强转可能会出现ClassException异常)
格式: a instanceof A;判断对象a是否是类A的实例,是true,不是false
为了避免在向下转型时出现ClassException异常,我们在向下转型之前,先进行instanceof判断,返回true进行,false不进行(if条件句)
如果 a instanceof A返回true,则 a instanceof B也返回true,其中类B是类A的父类。
若子类重写了父类的方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中
对于实例变量则不存在这样的现象,即使子类里定义了父类完全相同的实例变量,这个变量依然不可能覆盖父类中定义的实例变量
9.Object类的使用
java.lang.Object类
1.Object类是所有Java类的根父类
2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Objec类
3.Object类中的功能(属性方法)就具有通用性
4.Object类只声明了一个空参的构造器
==和equals()区别
1.==:运算符
可以使用在基本数据类型变量和引用数据类型变量中
如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等(不一定类型要相同)
如果比较的是引用数据类型变量,比较两个变量的地址值是否相同
2.equals()方法
是一个方法而非运算符
只能适用于引用数据类型
Object类中equals()的定义:
public boolean equals(Object obj){
return (this==obj);
}
//说明:Object类中定义的equals()和==作用相同,比较地址值
像String、Date、File、包装类等都重写了Object类中的equals()方法,重写以后比较的不是两个引用的地址是否相同,而是比较两个对象的“实体内容”是否相同。
toString()用法
1.当我们输出一个对象的引用时,实际上就是调用当前对象的)String()
2.Object类中toString()的定义
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
3.像String、Date、File、包装类等都重写了Object类中的toString()方法
使得在调用对象toString()时,返回“实体内容”信息
4.自定义类也可以重写toString()方法,放调用此方法时,返回对象的“实体内容”
例子
@Override
public String toString() {
return "Customer{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
10.包装类(Wrapper)的使用
1.单元测试:
步骤:
1.在IDEA工程中输入@test
将其添加到外部库
2.创建Java类:此类是public、提供公共的、无参的构造器
3.此类中去声明单元测试方法:方法权限是public、没有返回值、没有形参
4.此单元测试方法上需要添加@Test,并导入import org.junit.Test;
5.声明好单元测试方法以后,就可以在方法体内测试相关的代码
2.包装类的使用
1.Java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征。
2.掌握基本数据类型、包装类、String三者之间的相互转换
基本数据类型——>包装类:调用包装类的构造器
@Test
public static void main(String[] args) {
int num1=10;
Integer in1= num1;
System.out.println(in1.toString());
}
包装类——>基本数据类型:调用包装类的xxValue()
public void test2(){
Integer in1= 12;
int i1=in1.intValue();
System.out.println(i1+1);
}
基本数据类型、包装类——>String类型:调用String重载的valueOf(Xxx xxx)
public void test3(){
int num1=10;
String str1=num1+"";
float f1=12.3f;
String str2=String.valueOf(f1);
System.out.println(str2);
Double d1=new Double(12.4);
String str3=String.valueOf(d1);
System.out.println(d1);
}
String类型——>基本数据类型、包装类:调用包装类的parseXxx(String s)
public void test4(){
String str1="123";
int num1=Integer.parseInt(str1);
System.out.println(num1);
String str2="true";
boolean b1=Boolean.parseBoolean(str2);
System.out.println(b1);
}
例子
package java4;
import java.util.Scanner;
import java.util.Vector;
public class ScoreTest {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
Vector v=new Vector();
int maxScore=0;
for (; ; ) {
System.out.println("请输入学生成绩(负数代表输入结束):");
int score=scan.nextInt();
if(score<0){
break;
}
if(score>100){
System.out.println("输入数据废话,请重新输入");
continue;
}
// Integer score1=score;
// v.addElement(score1);
v.addElement(score);//自动装箱
if(maxScore<score){
maxScore=score;
}
}
char level;
for (int i = 0; i < v.size(); i++) {
Object obj=v.elementAt(i);
// Integer inScore=(Integer) obj;
// int score=inScore.intValue();
int score=(int)obj;
if(maxScore-score<=10){
level='A';
} else if (maxScore-score<=20) {
level='B';
}else if (maxScore-score<=30) {
level='C';
}else{
level='D';
}
System.out.println(i+1+"score is"+score+"level is"+level);
}
}
}