永不退缩 永不退缩

I,can do

目录
重新出发000008-阅读文章“八_面向对象”
/    

重新出发000008-阅读文章“八_面向对象”

首先我们定义一组对象,分别为:Animal(动物),Primat(灵长类动物),Money(猴子),Person(人类)

而他们的关系是:
WechatIMG44.jpeg

那么分别看代码:
Aminal:

package review.base.Java那些事儿.c8_oob;

/**
 * 第八节,面向对象的相关内容存放在这里。
 * 
 * 动物类,动物类是相当抽象的对象,并没有具体的属性,所以可以是一个接口,也相对比较合理。 
 */
 public interface Animal {
	/**
	 *   所有的动物都有eat(吃饭)的行为,但是不同的动物吃的行为是不一样的,所以无法具体的表述。 
	 *  所以eat这个方法在Animal接口中是无法具体实现的。 
	 */ 
	 void eat();

}

Primat:

package review.base.Java那些事儿.c8_oob;

/**
 * 灵长类动物继承了动物接口,所以也自动继承了动物eat(吃)的行为(继承的好处之一,不用重复写一次吃这个行为的代码) 
 */
public interface Primat extends Animal {

    /**
	 * 灵长类动物是可以行走的,所以此扩展了一个move(行走)的方法 
	 */  
	void move();

}

Monkey:

package review.base.Java那些事儿.c8_oob;

/**
 * 声明了一个猴子类,同Person相同的继承了Primat(灵长类),但是和Person又具有不同的属性。 
 */
 public class Monkey implements Primat {
    String name;

    public Monkey(String name) {
        this.name = name;
    }

    /**
	 * 同Person一样,需要实现接口的move方法,但是可以提供不同的实现内容。 
	 */  
	@Override
	public void move() {
        System.out.println(name+"吃起了香蕉");
    }

    @Override
	public void eat() {
        System.out.println(name+"在树上跳来跳去");
    }
}

Person:

package review.base.Java那些事儿.c8_oob;

import java.util.Objects;

/**
 * 人类这一层有了具体的属性(年龄和名字),再抽象称接口就不合理了,所以声明成了类 
 */
public class Person implements Primat {

    String name;

    String gender;

    private Integer age;

    /**
	 * 构造函数 * @param name 姓名
	 * @param gender 性别
	 * @param age 年龄
	 */  
	public Person(String name, String gender, Integer age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    @Override
	public void move() {
        System.out.println(name+"拿起碗和筷子吃饭");
    }

    @Override
	public void eat() {
        System.out.println(name+"站起来走路");
    }

    /**
	 * 由于年龄这个属性加入了private,外界无法获得,但我们可以提供一个public方法然外部可以访问。 
	 * 这个方法内部进行了处理,不然外界看到女士的年龄。 
	 */  
	public void sayAge(){
        if(isLady(gender)){
            System.out.println(name+"女士年龄保密");
        }else{
            System.out.println(name+age+"岁了");
        }
    }

    /**
	 * 判断性别是否为女性。由于采用了private,外部看不到,无法调用该方法,这就是封装。
	 * @param gender
	 * @return
	 */
	private boolean isLady(String gender) {
        if("女".equals(gender)){
            return true;
        }
        return false;
    }

    @Override
	public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) &&
                Objects.equals(gender, person.gender) &&
                Objects.equals(age, person.age);
    }

    @Override
	public int hashCode() {

        return Objects.hash(name, gender, age);
    }
}

正文开始:

package review.base.Java那些事儿;

import review.base.Java那些事儿.c8_oob.Animal;
import review.base.Java那些事儿.c8_oob.Monkey;
import review.base.Java那些事儿.c8_oob.Person;
import review.base.Java那些事儿.c8_oob.Primat;

public class 八_面向对象 {
    public static void main(String[] args) {
        System.out.println("a:面向对象是什么?\nb:面向对象就是封装、继承、多态 \na:然后呢?多态是什么?\nb:今天天气不错啊!");
        System.out.println();
        System.out.println("------正文开始-----------");

        Animal animal1 = new Monkey("monkey1");
        Animal animal2 = new Person("Eric", "男", 26);

        Primat primat = new Person("John", "男", 27);

        Person person1 = new Person("Yarn", "男", 26);
        Person person2 = new Person("Dan", "女", 27);

        System.out.println("\nanimal:");
        animal1.eat();          // 以Animal的形态出现,只能调用Animal里的eat方法,虽然Animal的eat没有实现,但是也能打印出我们期望的结果。
		animal2.eat();
		//  animal1.move();         // 编译无法通过,以Animal形态出现,只能调用Animal里的方法。
		((Monkey) animal1).move(); // 如果一定要调用,就需要强转。相当于明确告知这个Animal就是一个Money。
		//  ((Person) animal1).move(); // 但是如果animal1的类型不是Monkey时。就会引发新的问题。java.lang.ClassCastException

		System.out.println("\nprimat:");
        primat.eat();   // 以Primat形态出现,由于Primat继承了Animal,所以eat()和move()都可以调用。同理,Person的sayAge是无法使用的。
		primat.move();

        System.out.println("\nperson");
        // 以Person形态出现,既可以使用继承的方法,也可以使用自身的方法。
		person1.eat();
        person1.move();
        person1.sayAge();
        person2.sayAge();

        /**
		 * 参考文章地址:https://zhuanlan.zhihu.com/p/27681007
		 * 
		 * 在代码中,不管是动物,鸟类,人类,猴子,我们都可以抽象成类,类是对象的模板,通过new关键字,
		 * 可以创建一个个对象。仔细看蓝色框里的内容,animal1和animal2,虽然都是同一个形态(Animal), 
		 * 由于指向的是子类对象,当调用同一个eat()方法,运行时会智能匹配到子类的实现,最后得到的结果也不一样, 
		 * 这种形为,我们称之为多态。 
		 * 
		 * 多态满足的三个条件: 
		 * 1、要有继承。
		 * 2、要有重写。
		 * 3、父类引用指向子类对象。
		 * 
		 * ------ 
		 * 由于Person中age是private的,isLady()方法。是因为我们在该属性和方法前面加了private关键字。
		 * 隐藏了不想对客户端暴露的age属性和isLady()方法。
		 * 对于这种隐藏对象属性和实现细节,仅对外公开指定方法来控制程序中属性的访问和修改, 
		 * 我们称之为封装。(这儿我们没有对age提供set方法,压根没法修改,提供了一个printAge()方法供外部访问)。
		 */
  }
}