面向对象思想特征

封装(encapsulation)

把一系列功能打包到一起,只提供使用这些功能的界面;

即将一系列相关事物的共同的属性和行为提取出来,放到一个类中,隐藏对象的属性和实现细节,仅对外提供公共的访问方式。

封装的关键就是绝不能让类中的方法直接访问其他类中的数据,程序仅通过对象的方法与对象的数据进行交互

继承(inheritance)

让类与类之间产生父子关系

子类继承父类后,子类拥有了父类的非私有成员(成员变量,成员方法)

public class ExtendDemo01 {
    public static void main(String[] args) {
        Child child=new Child();
        child.setAge(22);//调用父类方法
        //child.age; age属于父类的私有成员变量,子类无法继承
        System.out.println(child.getAge());
    }
}
class Child extends Parent{
}
class Parent{
    public Parent(){}
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
}

一、继承关系中类成员的使用 

继承关系中父类成员变量的使用:

如果子类与父类中定义了同名的成员变量,如何使用?

①子类中定义成员变量int price=20

②父类中定义成员变量int price=10

③子类成员方法中定义局部变量int price=5

④子类成员方法中分别输出三个price的值

public class ExtendDemo03 {
    public static void main(String[] args) {
        Apple apple=new Apple();
        apple.showPrice();//有局部变量时,输出5
                          //没有局部变量,有子类成员变量时,输出10
                         //都没有时,输出20
    }
}
class Apple extends Fruit{
    //int price=10;
    public void showPrice(){
        //int price=5;
        System.out.println(price);
    }
}
class Fruit{
    int  price=20;
}

Java中使用变量的规则:遵循就近原则。局部位置有就使用,没有就去本类的成员位置找,有就使用,没有就去父类的成员位置找,有就使用,没有就报错。

     System.out.println(this.price);//本类中的成员变量      
System.out.println(super.price);//父类中的成员变量

super表示当前对象父类的引用

 

二、继承关系中子父类成员方法的使用

子父类中定义了同名的成员方法,如何使用?

   

public class ExtendDemo04 {
    public static void main(String[] args) {
        NineYin nineYin=new NineYin();
        nineYin.stroke();
        nineYin.internalStrength();
    }
}
class NineYin extends Martial{
    public void internalStrength(){//在父类的基础上作拓展
        super.internalStrength();//调用父类成员方法
        System.out.println("以柔克刚");//重写了父类的成员方法
    }
    public void stroke() {//直接覆盖了父类的方法
        System.out.println("九阴白骨爪");
    }
}
class Martial{//武功类
    //练习内功
    public void internalStrength(){
        System.out.println("练习内功");
    }
    //练习招式
    public void stroke(){
        System.out.println("练习招式");
    }
}

访问父类方法的方式:super.父类方法名

三、继承关系中子父类构造方法的使用

1、创建对象时,构造方法是如何被调用的?

①定义Person类,在默认无参构造中输出语句

②定义Worker类继承Person类,在默认无参构造中输出语句

③创建子类Worker对象

public class ExtendDemo05 {
    public static void main(String[] args) {
     Worker worker=new Worker();
    }
}
class Worker extends Person{
    public Worker(){
        System.out.println("worker");
    }
}
class Person{
   public Person(){
       System.out.println("person");
   }
}
输出结果为:person
          worker

创建子类对象时,会优先调用父类的构造方法

子类构造方法的第一行,隐含语句super(),用于调用父类默认无参构造

2、父类中不存在默认无参构造方法怎么办?

子类创建对象时,必须先初始化该对象的父类内容,若父类中不存在默认无参构造,须手动调用父类有参数的构造方法。

public class ExtendDemo06 {
    public static void main(String[] args) {
        Worker1 worker=new Worker1();
    }
}
class Worker1 extends Person1{
    public Worker1(){
        super("wangyingjing");//没有这一句时,系统会报错,提示父类没有默认无参构造
        System.out.println("worker");
    }
}
class Person1{
    public Person1(String name){
        System.out.println("person"+name);
    }
}

四、Java中继承的特点

  1. 单继承

    Java中只支持类的单继承,但是支持多层继承

    Java支持接口的多继承,语法:接口A extends 接口B,接口C,接口D...

  2. 父类私有成员不能继承

  3. 构造方法不能继承,构造方法是用于初始化本类对象,继承没有意义。但在创建子类对象时要调用父类的构造方法进行初始化。

  4. 子类只有一个父类

多态(polymorphism)

多种状态,同一对象在不同情况下表现出不同的状态或行为

1、Java中实现多态的步骤:

  1. 要有继承(或实现(类和接口之间的关系))关系

  2. 要有方法重写

  3. 父类引用指向子类对象

public class DuoTaiDemo01 {
    public static void main(String[] args) {
        //演示多态
        /*实现多态:有继承或实现关系
        有方法重写
        要有父类引用指向子类对象
         */
        
        Animal1 animal1=new Dog1();   //要有父类引用指向子类对象
         //编译看左,运行看右                              
 //多态中调用成员是看左边的类中有没有这个成员,运行时具体看用的是右边类中的该成员
         animal1.setName("花花");
         animal1.eat();//注释掉Animal1中的eat方法,这里会报错   
    }
}
class Dog1 extends Animal1{
    @Override
public void eat(){
        System.out.println(getName()+"是一只狗,它正在吃东西");
    }
}
class Animal1{
    public Animal1(){}
    public Animal1(String name){
        this.name=name;
    }
    private String name;

    public void setName(String name) {
        this.name = name;
    }
 public String getName() {
        return name;
    }
    public void eat(){
        System.out.println(name+"正在吃东西");
    }
}

2、多态的效果演示

需求:父类型变量作为参数时,可以接收任意子类对象

分析:- 定义方法,参数类型为父类型Animal:showAnimal(Animal animal)

           -分别创建Dog类和Mouse类的对象

           -调用showAnimal方法演示效果

public class DuoTaiDemo02 {
    public static void main(String[] args) {
        //用来测试Dog类和Mouse类
       //测试Dog类
        Dog2 dog2=new Dog2();
        dog2.setName("花花");
        showAnimal2(dog2);
        //测试老鼠类
        Mouse mouse=new Mouse();
        mouse.setName("小小");
        showAnimal2(mouse);
    }
/* 传统测试方法
    public static void showAnimal2(Dog2 dog2){
        dog2.eat();
    }
    public static void showAnimal2(Mouse mouse){
        mouse.eat();
    }

        */
    //多态
   //多态的使用场景:父类型可以作为形参的数据类型,这样可以接收其任意的子类对象
    public static void showAnimal2(Animal2 animal2){
        animal2.eat();}}
class Dog2 extends Animal2{
    @Override
    public void eat(){
        System.out.println(getName()+"正在吃东西");
    }
}
class Mouse extends Animal2{
    public void eat(){
        System.out.println(getName()+"在吃东西");
    }
}
class Animal2{
   private String name;
    public Animal2(){
    }
    public Animal2(String name){
        this.name=name;
    }
    public void setName(String name) {
        this.name = name;
    }
public String getName() {
        return name;
    }
    public void eat(){
        System.out.println(name+"吃东西");
    }
}

3、多态关系中成员变量的使用

多态关系中成员变量的使用:

子父类中定义了同名的成员变量,如何调用?

package com.wang.duixiang;

public class DuoTaiDemo03 {
    public static void main(String[] args) {
        Animal3 animal3=new Dog3();
        System.out.println(animal3.name);
        Dog3 dog3=new Dog3();
        System.out.println(dog3.name);
    }
}
class Dog3 extends Animal3{
    String name="Dog3";
}
class Animal3{
    String name="Animal3";
}
输出结果为:Animal3
          Dog3

多态关系中,成员变量不能重写。并且使用成员变量时,编译看左,运行看左 

4、多态的好处和弊端

①可维护性 基于继承关系,只需要维护父类代码,提高了代码的复用性,大大降低了维护程序的工作量

②可拓展性 把不同的子类对象都当作父类看待,屏蔽了不同子类对象间的差异,做出通用的代码,以适应不同的        需求,实现向后兼容

弊端:不能使用子类特有成员

当需要使用子类特有功能时,需要进行类型转换:向上转型:Animal animal=new Dog()

                                                                                     向下转型:Dog dog=(Dog)animal

注意:只能在继承层次内进行转换,否则会出现(ClassCastException类型转换异常)

           将父类对象转换为子类之前,使用instanced进行检查

public class DuoTaiDemo04 {
    public static void main(String[] args) {
        //通过多态创建对象
        Animal4 animal4=new Dog4();
        animal4.eat();
        //调用子类独有的方法
        if(animal4 instanceof Dog4){//判断animal4是否是Dog4类的对象
            Dog4 dog4=(Dog4)animal4;
            dog4.watch();}
    }
}
class Dog4 extends Animal4{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    //狗类中独有的方法,父类中没有
    public void watch(){
        System.out.println("狗可以看家");
    }
}
class Animal4{
    public void eat(){
        System.out.println("吃东西");
    }
}
原文地址:https://www.cnblogs.com/wyj96/p/11749207.html