java-类与对象总结(下)

一、面向对象三大特性之继承

继承最重要的作用就是实现代码的复用,不但可以使用已有基类所有的功能,而且派生类可以在不改变原有基类的情况下对这些功能进行扩展。

1、继承的实现:

在 java 中,继承使用 extends 关键字来实现,定义的语法如下:

    class [子类] extends [父类]

2、继承的限制:

    1)java不允许多重继承,但是允许多层继承

一个子类只能继承一个父类,因为java不允许多重继承,但是可以通过多层继承的方式,使C同时继承A和B的方法。

class A{
    public void functionA(){}
}
class B extends A{
    public void functionB(){}
}
class C extends B{
    public void functionC(){}
}

    2)子类对象在实例化之前,一定会首先实例化父类。

实际上在子类的构造方法之中,相当于隐含一个 super()语句,在父类提供无参构造的时候可以不写,但如果父类定义多个构造方法,则必须使用super()语句指明所要调用的构造方法。

class Person{
    public Person(){
        System.out.println("父类A实例化");
    }
}
class Student extends Person{
    public Student(){
        //super();    父类提供无参构造的时候可以不写
        System.out.println("子类B实例化");
    }
}
public class Demo{
    public static void main(String[] args) {
        Student student=new Student();
    }
}

运行结果如下:

    3)子类会继承父类的所有属性和方法,其中非私有部分属于显示继承,子类可以直接调用;而父类中使用private修饰的私有部分,属于隐式继承,子类无法直接使用,需通过其他方式调用(例如setter和getter)。

3、super关键字:

上面我们说到如果父类定义多个构造方法,则子类在构造时必须使用super()语句指明所要调用的构造方法。

此外,使用super还可以在子类中调用父类的非私有方法和属性。

那么,super和this的区别有哪些:

    1)super从子类中调用父类的非私有方法和属性,不查找子类而直接调用父类定义,。

    2)this优先调用本类中的方法和属性,先查找本类,如果本类没有才调用父类。

因此,两者最大的区别在于,super调用的一定是父类的方法,而this却不一定。

4、覆写(override)

所谓覆写,指的是子类在继承父类时,又重新定义了与父类相同的方法或者属性。那么为什么要覆写,简单来讲就是继承来的属性和方法不能满足子类的需求,从而重新改造以满足需求。

     1)属性的覆写(了解概念即可)

子类定义了与父类属性名称完全相同的属性,就是属性的覆写。

这种操作本身没有意义,因为属性一般都使用private封装,子类不知道父类有什么属性,那么也就不存在属性覆写的问题。

     2)方法的覆写(重要)

子类定义了与父类方法名、参数类型及个数完全相同的方法,就是方法的覆写。

需要注意的是,子类覆写的方法不能拥有比父类更严格的访问权限。

(访问权限:public  > protected > default >  private,如果父类的访问权限是public,那么子类只能使用public,如果父类的访问权限是default,那么子类可以使用的权限有public 、protected以及default )

class Person{
    public void function(){
        System.out.println("父类的方法");
    }
}
class Student extends Person{
    public void function(){
        System.out.println("子类的方法");
    }
}
public class Demo{
    public static void main(String[] args) {
        Student student=new Student();
        student.function(); //此时打印的是“子类的方法”
    }
}

5、总结一下重载和重写(覆写)的区别:

     重载:一个类中有两个及以上方法名相同的方法,但参数类型、参数个数、参数顺序不同,则称为方法的重载。特别注意返回值类型不同不能重载。

     重写:发生在父类和子类之间,子类在继承父类时,又重新定义了与父类方法名相同、参数列表相同,返回值类型相同(协变类型)的方法。需要注意重新定义的方法访问修饰符的限制不能比父类更加严格。

总之,重载和覆写是Java多态性的不同表现。前者是在一个类中多态性的表现,后者是在父类和子类两个类之间多态性的表现。

6、final关键字: 在Java中final被称为终结器。

     1)使用final可以修饰类、方法、属性

         修饰类     -->成为密封类,不允许被继承

         修饰变量  -->变量变为常量,在声明时必须初始化,不能再次赋值

         修饰常量  -->常量名命名全部使用大写字母,多个单词之间用下划线_隔开

         修饰方法  -->成为密封方法,不能重写

     2)final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。

     3)使用final定义的类不能有子类(String类便是使用final定义)

     4)final一旦修饰一个类之后,该类的所有方法默认都会加上final修饰(不包含成员变量)


二、面向对象三大特性之多态

Java中的多态,核心表现主要有以下两点:

1、方法的多态性:

    1)方法的重载:调用同一方法名,可以根据参数列表的不同,实现不同的功能。

    2)方法的重写:同一父类的方法,不同的实例化子类有不同的实现。

2、对象的多态性:(前提是方法覆写)

    1)对象的向上转型(自动):父类 父类对象 = 子类实例

观察向上转型:我们依然使用上面的例子

class Person{
    public void function(){
        System.out.println("父类实例");
    }
}
class Student extends Person{
    public void function(){
        System.out.println("子类实例");
    }
}
public class Demo{
    public static void main(String[] args) {
        Person person=new Student();
        person.function(); //打印的是“子类实例”
    }
}

可以发现,如果子类覆写了父类的方法,那么就调用子类覆写后的方法,如果子类没有覆写,那么就会调用父类的方法。核心本质在于使用的是哪个子类(new在哪里),以及调用的方法是否被子类覆写。

那么为什么要使用向上转型:主要作用是可以实现接收参数的统一

class Person{
    public void function(){
        System.out.println("我是人类");
    }
}
class Student extends Person{
    public void function(){
        System.out.println("我是学生");
    }
}
class Teacher extends Person{
    public void function(){
        System.out.println("我是老师");
    }
}
public class Demo{
    public static void main(String[] args) {
        //实现接收参数的统一
        whoYouAre(new Student());    
        whoYouAre(new Teacher());
    }
    public static void whoYouAre(Person pre){
        pre.function();
    }
}

       2)对象的向下转型(强制):子类 子类对象 = (子类)父类实例

对象的向下转型,是强制将父类对象变为子类对象,我们为什么要这样做:就是为了使用子类扩充的操作。

class Person{
    public void function(){
        System.out.println("父类方法");
    }
}
class Student extends Person{
    public void function(){
        System.out.println("子类方法");
    }
    public void print(){
        System.out.println("子类独有的打印方法");
    }
}
public class Demo{
    public static void main(String[] args) {
        Person person=new Student();
        person.function();
        //此时只能使用父类定义好的方法,不能使用Student类中的printf方法

        Student student = (Student)person;  //强制向下转型
        student.print();     //现在可以访问子类独有的打印方法
    }
}

需要注意的是,并不是所有的父类对象都可以向下转型 :如果想要向下转型,首先一定要发生向上转型,否则在转型时会出现 ClassCastException,因此向下转型存在安全隐患。

为安全起见,在向下转型之前需要判断是否已经发生了向上转型,此时可以使用instanceof关键字判断。

Person person = new Student();
    if (person instanceof Student) { //避免ClassCastException
        Student student = (Student) person ;
        student.print();
    }

多态总结:

    1)对象的多态性的前提是方法覆写。

    2)通过对象的向上转型可以实现接收参数的统一。

    3)通过向下转型可以实现对子类扩充方法的调用(有安全隐患一般不用)。

    4)两个没有关系的类对象不能转型,否则会出现ClassCastException。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值