一个Java面向对象的小练习

一:项目需求与解决思路;

  学习了这么长时间的面向对象,我们只是对面向对象有了一个简单的认识,我们现在来做一个小练习,这个例子可以使大家更好的掌握面向对象的特性:
  1.人类都有说话的能力,那我们可不可以使用计算机程序来描述其特征呢。  2.如果是中国人,那么他的语言能力就直接输出中国人说中国话、如果是美国人,那么他的语言能力就直接输出美国人说美国话。  3.分别在测试类中创建两个对象,创建了中国人对象的话,他应该说的是中国话,创建了美国人的话,他应该说的是英语。  4.那么如何用我们的面向对象知识实现这一特点呢,  5.首先我们分析一下,中国人和美国人都是人类,也就是我们说的 is a 关系,那我可不可以用到面向对象的继承关系呢,只不过中国人的语言能力我们要输出中国人说中国话,美国人的语言能力我们要输出美国人说英语,显然如果我要写成继承的关系的话,有人类这样一个父类,但是人类这个父类里的语言能力满足不了我们的需求,因为我们发现子类中都有自己的语言能力,那现在怎么办呢,我们是不是就可以用到面向对象中的重写方法特性呢,我们知道,如果父类无法满足子类的需求那么我们就重写从父类继承来的方法,我们是不是就可以解决这个问题了呢,  6.最终我们在创建两个对象的时候,我们可以思考一下这个问题,我可不可以用多态的特性来解决这个问题呢,因为不管是中国人也好美国人也好他们都是人类,我们可不可以用父类的引用指向子类的对象呢,那结合以上我们分析的特点,我们的程序就写出来了。  7.所以我们写的任何一个程序我们都要思考能否用前面学习的方法来实现。  我们来看一下代码如何实现:

二:代码的实现与优化;

  1.我们先创建一个工程,名为Demo;
图片描述

  2.那我们说中国人和美国人都是人,所以我们应该有一个人类的父类,我们取名为Person类:当然要加我们的包名;

图片描述
  3.那人类有什么能力呢,当然有说话的能力,我们定义一个say()方法;
图片描述
  4.那么中国人也是人,美国人也是人,他们要继承于Person这个父类,我们再来创建一个子类;
图片描述
当然我们需要继承父类,所以修改代码为;
图片描述
  显然,子类虽然有说话的能力,但是满足不了我们的需求,所以我们要重写子类的方法,代码如下;

package com.demo;

public class Chinese extends Person{
    
    public void say(){
        System.out.println("中国人说中国话");
    }
}

  我们的第二个子类也如上;
图片描述
代码如下:

package com.demo;

public class American extends Person{
    
    public void say(){
        System.out.println("美国人说英语");
    }

}

    

  5.现在我们写一个测试类;
图片描述
代码如下:

package com.demo;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Chinese p = new Chinese();//创建一个对象通过引用p指向它
        American p2 = new American();//创建一个对象通过引用p2指向它
        p.say();
        p2.say();
    }

}

运行结果为:
图片描述
  6.那我们发现中国人和美国人都是人,我们可不可以用父类的引用指向子类的对象呢,用上我们多态的语法,当然是可以的,代码如下:

package com.demo;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Person p = new Chinese();//创建一个对象通过引用指向它
        Person p2 = new American();//创建一个对象通过引用指向它
        p.say();
        p2.say();
    }

}

注:只有两个类有继承关系的时候才能使用多态;运行结果为:
图片描述

  7.那我们再来想一想可不可以用更好的方法来实现这个程序呢,因为Person类其实只是充当了一个制定规则的父类,我们还可以使用抽象类来表示!因为我们只是用Person类充当父类制定规则,并不会用到Person类中的方法;
  先创建一个类;
图片描述
代码如下:

package com.demo;

public abstract class APerson {

    //方法声明
    public abstract void say();
}

我们继续修改子类让其继承抽象类APerson;

package com.demo;

public class Chinese extends APerson{
    
    public void say(){
        System.out.println("中国人说中国话");
    }
}
package com.demo;

public class American extends APerson{
    
    public void say(){
        System.out.println("美国人说英语");
    }

}
package com.demo;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        APerson p = new Chinese();//创建一个对象通过引用指向它
        APerson p2 = new American();//创建一个对象通过引用指向它
        p.say();
        p2.say();
    }

}

运行结果为:
图片描述
  那么我们的运行结果虽然是一样的,但是我们的代码更合理了!