14.面向对象三大特征

一、封装与隐藏

package com.atguigu.java;
/*
 * 面向对象的特征一:封装与隐藏     3W:what? why? how?
 * 一、问题的引入:
 *  当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受到
 *  属性的数据类型和存储范围的制约。除此之外,没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值
 *  加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。(比如:setLegs())
 *  同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private).
 *  -->此时,针对于属性就体现了封装性。
 * 
 * 二、封装性的体现:
 * 我们将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值
 * 
 *  拓展:封装性的体现:① 如上  ② 不对外暴露的私有的方法  ③ 单例模式   ...
 *  
 * 
 * 三、封装性的体现,需要权限修饰符来配合。
 * 1.Java规定的4种权限(从小到大排列):private、缺省、protected 、public 
 * 2.4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
 * 3.具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
 *        修饰类的话,只能使用:缺省、public
 * 
 * 总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
 * 
 */
public class AnimalTest {
    public static void main(String[] args) {
        
        Animal a = new Animal();
        a.name = "大黄";
//        a.age = 1;
//        a.legs = 4;//The field Animal.legs is not visible
        
        a.show();
        
//        a.legs = -4;
//        a.setLegs(6);
        a.setLegs(-6);
        
//        a.legs = -4;//The field Animal.legs is not visible
        a.show();
        
        System.out.println(a.name);
        
    }
}


class Animal{
    
    String name;
    private int age;
    private int legs;//腿的个数
    
    //对属性的设置
    public void setLegs(int l){
        if(l >= 0 && l % 2 == 0){
            legs = l;
        }else{
            legs = 0;
//            抛出一个异常(暂时没有讲)
        }
    }
    
    //对属性的获取
    public int getLegs(){
        return legs;
    }
    
    
    public void eat(){
        System.out.println("动物进食");
    }
    
    public void show(){
        System.out.println("name = " + name + ",age = " + age + ",legs = " + legs);
    }
    
    //提供关于属性age的get和set方法
    public int getAge(){
        return age;
    }
    public void setAge(int a){
        age = a;
    }
    
}

//private class Dog{
//    
//}
package com.atguigu.java;

public class Order {
    
    private int orderPrivate;
    int orderDefault;
    public int orderPublic;
    
    
    private void methodPrivate(){
        orderPrivate = 1;
        orderDefault = 2;
        orderPublic = 3;
    }
    void methodDefault(){
        orderPrivate = 1;
        orderDefault = 2;
        orderPublic = 3;
    }
    public void methodPublic(){
        orderPrivate = 1;
        orderDefault = 2;
        orderPublic = 3;
    }
    
}
package com.atguigu.java;

public class OrderTest {
    public static void main(String[] args) {
        
        Order order = new Order();
        
        order.orderDefault = 1;
        order.orderPublic = 2;
        //出了Order类之后,私有的结构就不可以调用了
//        order.orderPrivate = 3;//The field Order.orderPrivate is not visible
        
        
        
        order.methodDefault();
        order.methodPublic();
        //出了Order类之后,私有的结构就不可以调用了
//        order.methodPrivate();//The method methodPrivate() from the type Order is not visible
    }
}
二、面向对象的特征之二:继承性
package com.atguigu.java;
/*
 * 面向对象的特征之二:继承性    why?
 * 
 * 一、继承性的好处:
 * ① 减少了代码的冗余,提高了代码的复用性
 * ② 便于功能的扩展
 * ③ 为之后多态性的使用,提供了前提
 * 
 * 
 * 二、继承性的格式: 
 *    class A extends B{}
 *    A:子类、派生类、subclass
 *    B:父类、超类、基类、superclass
 *    
 *    2.1体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。
 *        特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。
 *    只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
 *    2.2 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
 *    子类和父类的关系,不同于子集和集合的关系。
 *    extends:延展、扩展
 * 
 * 三、Java中关于继承性的规定:
 *       1.一个类可以被多个子类继承。
 *    2.Java中类的单继承性:一个类只能有一个父类
 *    3.子父类是相对的概念。
 *    4.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
 *    5.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
 *    
 *  
 * 四、 1. 如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
 *    2. 所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
 *    3. 意味着,所有的java类具有java.lang.Object类声明的功能。
 */
public class ExtendsTest {
    public static void main(String[] args) {
        
        Person p1 = new Person();
//        p1.age = 1;
        p1.eat();
        System.out.println("*****************");
        
        Student s1 = new Student();
        s1.eat();
//        s1.sleep();
        s1.name = "Tom";
        s1.setAge(10);
        System.out.println(s1.getAge());
        
        s1.breath();
        
        
        Creature c = new Creature();
        System.out.println(c.toString());
    }
}

三、面向对象特征之三:多态性

package com.atguigu.java;

import java.util.Date;

/*
 * 面向对象特征之三:多态性
 * 
 * 1.理解多态性:可以理解为一个事物的多种形态。
 * 2.何为多态性:
 *   对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
 *   
 * 3. 多态的使用:虚拟方法调用
 *   有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
 *   总结:编译,看左边;运行,看右边。
 *   
 * 4.多态性的使用前提:  ① 类的继承关系  ② 方法的重写
 * 
 * 5.对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
 * 
 * *************************************************************
 * 
 * 
 */
public class PersonTest {
    public static void main(String[] args) {
        
        Person p1 = new Person();
        p1.eat();
        
        Man man = new Man();
        man.eat();
        man.age = 25;
        man.earnMoney();
        
        //*************************************************
        System.out.println("*******************");
        //对象的多态性:父类的引用指向子类的对象
        Person p2 = new Man();
//        Person p3 = new Woman();
        //多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写父类的方法 ---虚拟方法调用
        p2.eat();
        p2.walk();
        
        
//        p2.earnMoney();
        
        System.out.println(p2.id);//1001
        
        System.out.println("****************************");
        //不能调用子类所特有的方法、属性:编译时,p2是Person类型。
        p2.name = "Tom";
//        p2.earnMoney();
//        p2.isSmoking = true;
        //有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致
        //编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
        
        //如何才能调用子类特有的属性和方法?
        //向下转型:使用强制类型转换符。
        Man m1 = (Man)p2;
        m1.earnMoney();
        m1.isSmoking = true;
        
        //使用强转时,可能出现ClassCastException的异常。
//        Woman w1 = (Woman)p2;
//        w1.goShopping();
        
        /*
         * instanceof关键字的使用
         * 
         * a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
         * 
         * 
         *  使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
         *  进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
         *  
         *  如果 a instanceof A返回true,则 a instanceof B也返回true.
         *  其中,类B是类A的父类。
         */
        if(p2 instanceof Woman){
            Woman w1 = (Woman)p2;
            w1.goShopping();
            System.out.println("******Woman******");
        }
        
        if(p2 instanceof Man){
            Man m2 = (Man)p2;
            m2.earnMoney();
            System.out.println("******Man******");
        }
        
        if(p2 instanceof Person){
            System.out.println("******Person******");
        }
        if(p2 instanceof Object){
            System.out.println("******Object******");
        }
        
//        if(p2 instanceof String){
//            
//        }
        
        //练习:
        //问题一:编译时通过,运行时不通过
        //举例一:
//        Person p3 = new Woman();
//        Man m3 = (Man)p3;
        //举例二:
//        Person p4 = new Person();
//        Man m4 = (Man)p4;

        
        //问题二:编译通过,运行时也通过
//        Object obj = new Woman();
//        Person p = (Person)obj;
        
        //问题三:编译不通过
//        Man m5 = new Woman();
        
//        String str = new Date();
        
//        Object o = new Date();
//        String str1 = (String)o;
        
        
        
    }
}

//class Order{
//    
//}

 

 

posted on 2019-12-29 10:13  南京咯咯  阅读(199)  评论(0编辑  收藏  举报

导航