资讯详情

Java学习教程(二)

第五章 继承,多态

第五章 继承,多态

一、继承性(extend)

二、方法的重写(overwrite/override)

三、四种权限修饰符(主要说明)protected)

四、super关键字

五、多态性

六、Object类的使用

七、==和equals()的区别

八、toString()

九、单元测试方法 包装类


一、继承性(extend)

有一个person类,要新建一个student类,其中student一些属性、方法和方法person里是一样的,这个时候就可以考虑继承,就会获得父类的属性和方法

public class Student extends Person{ //   写下自己没有定义,person有的student都有,构造器自己写  }

减少代码冗余,提高代码重用性;促进功能扩展;多态化的前提

class A extends B {}

A:子类衍生、subclass

B:超类、基类

1.父类声明为private子类继承父类后,仍然认为父类的私有结构已经获得。由于封装的影响,子类不能直接调用父类的结构

2.继承父类后,子类还可以声明其独特的属性和方法,实现功能的扩展。

3.java继承的规定:

一个类可以由多个子类继承

java中类单继承:一个类只能有一个父亲

子父是一个相对的概念:多层继承

子类直接继承的父类称为直接父类,间接继承称为间接父类

子类继承父类吼,获得直接父类和所有间接父类包含的属性和方法

4.如果父类没有明确声明,则继承于此类java.lang.Object类

所有的java类(除了他自己)直接或间接继承java.lang.Object

二、重写方法(overwrite/override)

1.子类可以根据需要改变从父类继承的方法。在实施过程中,子类的方法将覆盖父类的方法

2.区分重载和重写:

重载:对于具有相同返回类型和名称的方法,形参不同,构成方法之间的重载(两个相同)

重写:子类根据自己的需要重写继承的父类的方法,要求方法的返回类型、名称和形参相同

3.重写规定

方法的声明 权限修饰符 返回值类型 方法名(形参列表)throws 异常的类型{

//方法体

}

俗称:子类称重写法 父类被称为被重写的方法

①子类重写的方法名、形参类型和父类重写的方法名he形状参数表相同

② 权限修饰符:子类重写法的权限修饰符不小于父类重写法的权限修饰符

特殊:子类不能重写父类private方法

③返回值类型:

父类重写方法的返回值类型是void,子类重写法的返回值类型也是如此void

如果父类重写法的返回值类型是其他返回值类型,子类重写法可以是父类返回值类型或类型的子类(object和String)

父类重写方法的返回值类型为基本数据类型(如:double),子类重写法的返回值类型必须相同(如double)

④子类重写法抛出的异常类型不大于父类重写法抛出的异常类型

子类和父类同名参数的方法 要么都是非static(考虑重写)static(不是重写)

三、四种权限修饰符(主要说明)protected)

这里主要说四种不同的权限修改protected,可以看到不同包中的子类

四、super关键字

在我在子类中重写了一种方法后,我想用父类中重写的方法(生病了吗?

1.super理解为:父类

2.super可用于调用属性、方法、构造器

//        自己的ID 1001         System.out.println(id); //        父类的ID 1002         System.out.println(super.id);

3.可在子类方法或构造器中使用super.属性”或“super.方法”显示调用父类中声明的属性或方法。但是通常情况下会省略"super."

特殊情况:当同名属性在子类和父类中定义时,我们希望在子类中调用父类声明的属性,必须显示super.属性的方法表明调用了父性属性

4.方法:我在子类中重写了一种方法后,又想用父类中重写的方法,super.方法”

//        自己的eat 学生多吃营养丰富的食物   this.eat(); //        父类的eat 吃饭   super.eat();

5.构造器

①我们可以在子类 构造器中显式使用super(形参类声明的指定结构器(形参列表)

public Student (String name, int age,String major){     suer(name, age);//这个是父类里面的构造器
    this.major = major;
    
}

④在构造器的首行没有显式的声明“super(形参列表)”或“this(形参列表)”,则默认使用super()构造器

⑤在类的多个构造器中,至少有一个类的构造器中使用了“super(形参列表)”,调用父类中的构造器

五、多态性

可以理解为一个事物的多种形态

1.Person p2 = new Man();//Person是Man的父类

p2.eat() 执行的是Man子类的eat方法

就好比队列的定义: Queue que = new LinkedList();

多态的使用:当调用子父类中时,实际执行的是子类重写父类的方法---虚拟方法调用 即父类可以用子类中重写的方法

但是注意,p2能调的只有Person里的方法,即编译时是编译左边声明的类型,但是执行的时候是执行 Man里面的

3.多态的使用:虚拟方法的调用

有了对象的多态性后,我们在编译期,只能调用父类中声明的方法,在运行期,我们实际执行 的是子类重写的父类的方法

编译,看左边;运行,看右边

4.多态性使用前提:① 要有类的继承关系②方法的重写

 public static void main(String[] args) {
        AnimalTest test = new AnimalTest();
        
//    如果没有多态性,即使要执行相同的操作,也要写一个新的方法改变形参。
// 因此多态性可以省去重载方法        
        test.func(new Dog());//输出meat和dog
    }
//    如果没有多态性,即使要执行相同的操作,也要写一个新的方法改变形参。
// 因此多态性可以省去重载方法
    public  void func(Animal animal){  //Animal  animal = new Dog();
        animal.eat();
        animal.shout();
    }
}
class Animal{
    public void eat(){
        System.out.println("eat");
    }
    public void shout(){
        System.out.println("shout");
    }
}
class Dog extends Animal{
    public void eat(){
        System.out.println("meat");
    }
    public void shout(){
        System.out.println("wang");
    }
}

6.关于属性:对象的多态性只适用于方法 ,不适用于属性,左边定义的是谁,就是谁的属性

 

重载不表现为多态性

重写表现为多态性

7.instanceof

有了对象的多态性后,内存中实际上是加载了子类特有的的属性和方法的,但由于声明为父类类型,导致编译时只能调用父类中声明是属性和方法,子类特有的属性和方法不能调用。

如何调用子类特有的属性和方法?(要把对象改成子类的类型)将person类转为man类

Man m1 = (Man)p2;即(但这么写可能有风险) 下面讲instanceof

使用强转时可能出现ClassCastException异常

instanceof: 使用方法 : a instanceof A判断对象a是否是类A的实例,boolean类型

使用情景:用于向下转型前的判断

如果 a instanceof A 返回TRUE,则 a instanceof B,其中类B是类A的父类

==:对于引用数据类型,是比较两个引用数据类型变量的地址值是否相同

子类重写了父类方法以后,系统不能把父类里的方法转移到子类,但是对于实例变量,子类有和父类同名的实例变量也不可能覆盖父类里定义的实例变量

六、Object类的使用

1.是所有java类的根父类,没有显式声明extends谁的话,就默认是Object。

2.Object类中的功能(属性、方法)

3.Object只声明了一个空参构造器

七、==和equals()的区别

1.==的使用,

==:运算符,用于基本数据类型变量和引用数据类型变量

基本数据类型变量:比较数值(除了Boolean,其他的不计较类型,只比较数值)。不同数据类型比,int i= 10; double j= 10.0; i== j true

char k= 10; i==k true

引用数据类型变量:比较两个对象的地址值是否相同,及两个引用是否指向同一个实体。

2.equals()方法的使用

是一个方法,而非运算符

通过对象.equals()调用,因此无法用于基础数据类型,只能用于引用数据类型

Object类中equals的定义的方法和==的作用是相同的:比较两个对象的地址值是否相同

但是有一些引用变量类型数据,他们的equals是重写过的如:等都引用数据类型变量了Object()

中的equals, 比较两个象的“实体内容”是否相同(属性)

通常情况下,自定义的类如果使用equals()的话,可以对其进行重写以实现对于两个对象的实体内容是否相同

equals()可以自动生成,跟get(),set()一样

八、toString()

引用数据类型变量.toString() 输出的是地址值,及当我们输出一个对象的引用时,调用的是object类中的toString()方法

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

都重写了toString()。使得在调用对象的toString()方法是,返回“实体内容”的信息(想返回啥你自己写)

九、单元测试方法 包装类

:可以针对某一段代码进行测试

步骤: 1.build path->add libraries -> JUnit4

2.创建一个Java类进行单元测试。此时的Java类要求:类是公共的;提供一个公共的无参构造器;

3.在此类中声明单元测试方法:此时的单元测试方法:方法的权限是public,没有返回值,没有形参

4.此单元测试方法上需要声明注解:@Test并在单元测试类中导入对应的包:import org.junit.Test

5。声明好单元测试方法以后们就可以在方法体内测试相关代码

6.写完代码后,左键双击单元测试方法名,右键 run as -JUnit Test

说明:执行结果没有任何异常,绿条 否则是红条

面向对象都是针对类来说的,但是基本数据类型并不具备类的特点和功能,所以针对每个基本数据类型,都给他们设计了一个类把他们包起来了

 

基本数据类型,包装类,string之间的相互转换

1.基本数据类型->包装 

2.包装类->基本数据类型

调用包装类XXX的XXXValue()

补充:自动装箱和自动拆箱(不需要用构造器构造包装类了)

int num1 = 10;
Integer in2 = num1;

int num3  = in2;

3.基本数据类型、包装类--->String类型 valueOf

int num = 10;
//方式一:连接运算
String str1 = nums1 + "";

//方式二: 调用String的valueOf(XXX)
float f1 = 12.3f;
String str2 = String.valueOf(f1);//"12.3"

Double d1 = new Double(12.4);
String str3 = String.valueOf(d1);//"12.4"

4.String类型-->基本数据类型包装类 parseXXX


float f1 = 12.3f;
String str2 = Float.parseFloat(f1);//"12.3"

//注意此时的boolean类型有些特殊;
String str2 = "true1";
boolean b1 = Boolean.parseBoolean(str2);
//此时就会报错,布尔类型会严格检查是不是true 或 false,但是不区分大小写

注:对于三元运算符 X? A:B 一般要求A,和B是相同类型,如果类型不同会进行类型提升

 Integer内部定义了Integer cache,保存-128~127范围整数,使用自动装箱方式给Integer赋值,在上面这个范围内的可以直接用cache里的数,不需要再new,提高效率

标签: 02重载连接器he

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台