面向对象的三大特性

面向对象的三大特性

封装

什么是封装:

​ 在类中,对于不想被类外直接访问的成员变量,进行一个私有化,同时提供一个公共的方法访问私有的成员,尽可能的隐藏内部的细节,控制修改以及访问对象的权限。

封装的步骤:

  • 添加private修饰符(private私有的,只能本类内进行访问,这样就限制了外部其他类访问的权限)

  • 添加get和set方法(对外暴露的公共方法,每次外部类想要修改或者访问属性的时候,必须通过公共的方法)

    语法:

    //get方法
    public 属性类型  getXXX(){
        return 属性;
    }
    //set方法
    public 属性类型  setXXX(参数类型  参数){
        this.xxx=参数;
    }
    

    示例:

    public class Person { 
        private String name; 
        private int age; 
        private String sex; 
        public String getName() { 
            return name; 
        }
        public void setName(String name) { 
            this.name=name; 
        }
        public int getAge() { 
            return age; 
        }
        public void setAge(int age) { 
            if(age>100||age<1) {
                this.age=18; 
            }else { 
                this.age=age; 
            } 
        }
        public String getSex() { 
            return sex; 
        }
        public void setSex(String sex) { 	                       	        
           if(sex.equals("男")||sex.equals("女")) { 
                 this.sex=sex; 
             }else { 
                this.sex="男"; 
             } 
         }
        public void eat() {
            System.out.println(name+"开始吃饭..."); 
        }
        public void study() { 
            System.out.println(name+"开始努力学习..."); 
        }
        public void show() { 
            System.out.println("姓名:"+name+" 年龄:"+age+" 性     别:"+sex); 
        } 
    }
    
继承

概念:

​在原有类的基础上,产生一个新的类,在新的类中可以访问原有类中的非私有成员,并且可以添加自己独有的成员,这个过程叫做继承,简单理解为一个类继承了另外的一个类。

好处:

​ 实现代码的重复利用;模拟了现实世界的关系。

类的继承的使用:

​ 使用extends关键字实现2个类的继承关系;被继承的类叫做父类,超类,基类,继承的类叫做子类,派生类;继承之间需要满足 is a 的关系。

语法:

public class FatherClass{ 
	//属性 //方法 
}
public class ChildClass extends FatherClass { 
	//属性 //方法 
}

子类对象实例化的过程:

​ 先实例化父类对象,默认调用父类的构造方法,然后在实例化子类对象

不能被子类继承的成员:

  • 私有成员
  • 构造方法:父类的构造方法不能被子类所继承,但是会在子类的构造方法中调用(子类的构造方法,默认第一句是调用父类的构造方法:super())

继承的特点:

  • ​ 单继承:一个子类只能有一个父类,一个父类可以有多个子类,所有继承的资源非常的珍贵
  • 传递性:继承具有传递性,即爷爷的公共方法或者属性,孙子也有。

注意:

this 当前对象 :
1.区别局部变量和实例变量 this.属性 this.方法
2.this() 调用本类里的其他构造方法

super 父类:

​ 1.super 调用父类的属性和方法
​ 2.super() 调用父类的构造方法

所有构成继承的关系的类,所有子类的构造函数都默认提供

​ super(),即先调用父类的构造方法再调用子类的构造方法

​ super和this不能再同一个构造函数中出现

多态

什么是多态:

​ 在生活中,一类事物有多种的表现形态,对象的多种形态,比如:某个音乐家有三个儿子,大儿子会唱美声,二儿子会唱流行,三儿子唱摇滚。

​ 程序中,多态:同一个父类引用类型,使用不同的子类实例而执行不同操作 ,一句话理解:父类变量,子类对象。或者叫做:父类引用指向子类对象。

​ 父类引用仅可调用父类所声明的属性和方法,不以调用子类独有的方法和属性如果子类覆盖了父类的方法,父类引用调用方法时会优先执行子类覆盖的方法。

案例:

​ 要求:

  1. 编写一个宠物类 Pet 属性:id,name,health,love ;方法有print(),打印信息,要封装成员变量。

  2. 两个子类狗狗和猫类,狗狗有品种(strain),猫类有爱好(hobby),重写父类print()方法

  3. 3.宠物饿了,需要主人给宠物喂食,狗狗吃狗粮、猫咪吃小鱼,吃完之后健康值狗狗增加3,猫咪增加5。

代码演示:

/*宠物类 */
package com.qf.day08;
public class Pet{
    private int id; 
    //id 宠物编号 
    private String name;
    // 宠物昵称 
    private int health;
    // 健康值 
    private int love;
    // 亲密度 
    public void setId(int id){ 
        this.id=id; 
    }
    public int getId(){ 
        return id; 
    }
    public void setName(String name){ 
        this.name=name; 
    }
    public String getName(){ 
        return name; 
    }
    public void setHealth(int health){ 
        this.health=health; 
    }
    public int getHealth(){ 
        return health; 
    }
    public void setLove(int love){ 
        this.love=love; 
    }
    public int getLove(){ 
        return love; 
    }
    //方法 
    public void print(){ 
        System.out.println("宠物id:"+this.id+",宠物昵称:"+this.name+",健康值:"+health+", 亲密度:"+love); 
    } 
}
/*dog类继承Pet类 */
package com.qf.day08; 
public class Dog extends Pet{ 
    private String strain; 
    public void setStrain(String strain){ 
        this.strain=strain; 
    }
    public String getStrain(){ 
        return strain; 
    }
    public void print(){ 
        int id=getId(); 
        String name=getName(); 
        int health=getHealth(); 
        int love=getLove(); 
        System.out.println("狗狗id:"+id+" 昵称:"+name+" 健康值:"+health+" 亲密度:"+love+" 品种:"+strain); 
    }
    public void eat(){ 
        String name=getName(); 
        System.out.println(name+"大口吃狗粮...."); 
        //增加健康值 
        int health=getHealth(); 
        setHealth(health+3); 
    } 
}
/*猫类*/
package com.qf.day08; 
public class Cat extends Pet{ 
    private String hobby; 
    public void setHobby(String hobby){ 
        this.hobby=hobby; 
    }
    public String getHobby(){ 
        return hobby; 
    }
    public void print(){ 
        int id=getId(); 
        String name=getName(); 
        int health=getHealth(); 
        int love=getLove(); 
        System.out.println("猫咪id:"+id+" 昵称:"+name+" 健康值:"+health+" 亲密度:"+love+" 爱好:"+hobby); 
    }
    public void eat(){ 
        String name=getName(); 
        System.out.println(name+"大口吃小鱼...."); 
        //增加健康值 
        int health=getHealth(); 
        setHealth(health+5); 
    } 
}
/*主人*/
package com.qf.day08; 
public class Master{ 
    private String name; 
    public void setName(String name){ 
        this.name=name; 
    }
    public String getName(){ 
        return name; 
    }
    //喂食 
    public void feed(Dog d){ 
        System.out.println(name+"要给狗狗喂食物..."); 
        d.eat();
        d.print(); 
    }
    public void feed(Cat c){ 
        System.out.println(name+"要给猫咪喂食物..."); 
        c.eat(); 
        c.print(); 
    } 
}

package com.qf.day08; 
public class TestPet{ 
    public static void main(String[] args){ 
        Dog afu=new Dog(); 
        afu.setId(120); 
        afu.setName("阿福"); 
        afu.setHealth(85); 
        afu.setLove(90); 
        afu.setStrain("拉布拉多"); 
        afu.print(); 
        Cat amao=new Cat(); 
        amao.setId(119); 
        amao.setName("阿猫"); 
        amao.setHealth(90); 
        amao.setLove(70); 
        amao.setHobby("爬树"); 
        amao.print(); 
        Master yuhuan=new Master(); 
        yuhuan.setName("玉环"); 
        yuhuan.feed(afu); 
        yuhuan.feed(amao); 
    } 
}

思考:如果添加一个宠物需要给它喂食怎么办,就需要再写一个feed方法,这样就会显得代码的扩展性很差。

多态的使用:

  • 编写父类,子类,子类重写父类的方法
  • 运行时,使用父类的变量,子类的对象
//喂食 
//舍弃feed方法,进行重新的编写,
    public void feed(Dog d){ 
        System.out.println(name+"要给狗狗喂食物..."); 
        d.eat();
        d.print(); 
    }
    public void feed(Cat c){ 
        System.out.println(name+"要给猫咪喂食物..."); 
        c.eat(); 
        c.print(); 
    } 

//因为参数的类型为dog或者为cat,但是因为都继承了pet,所以使用pet当做参数
public void feed(Pet p){ 
    String n=p.getName(); 
    System.out.println(name+"要给"+n+"喂食物..."); 
    p.eat();//调用子类重写的方法 
    p.print();//调用子类重写的方法 
}

多态的使用形式:

  • 使用父类作为方法的形式参数
  • 使用父类作为方法的返回值实现多态
  • 重载,重写都是多态的表现形式
转型

因为存在了父类引用产生子类的,所以就有了转型

向上转型(装箱):将子类的对象赋值给父类变量,自动转换

Pet pet1 = new Dog(); 
Pet pet2 = new Cat(); 

String str = "abc"; 
Object obj = str;

注意:
    1 <父类型> <引用变量名> = new <子类型>(); 
	2 此时通过父类引用变量调用的方法是子类重写或父类的方法,编译时看父类,运行时看子类 
    3 此时通过父类引用变量无法调用子类特有的属性和方法

向下转型(拆箱):将父类的变量赋值给子类变量,强制转换

Object obj = new String("abc"); 
String str = (String)obj;

Pet pet=new Dog(); // Pet pet=new Cat(); 
Dog d=(Dog)pet; //向下转型 
注意: 
1 <子类型> <引用变量名> = (<子类型> )<父类型的引用变量>; 
2 在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常ClassCastException
instanceof关键字

​ 对象向下转型的时候,存在一个问题,若一个父类A的引用a,指向一个子类B的实例,将a赋值给另一个子类C引用时,会抛出java.lang.ClassCastException异常;抛出异常后程序将不能继续向下执行,为了避免这个异常的抛出,我们可以通过instanceof关键字判断引用指向的实例是否可以进行强制转换成某个子类对象。

已知Pet类有两个子类Dog和Cat:

public class Demo{ 
    public static void main(String[]args){ 
        Pet a = new Dog(); 
        check(a); 
    }
    //设计一个方法,判断一个动物是猫还是狗 
    public static void check(Pet a){ 
        if(a instanceof Dog){ //返回值类型是true/false
            System.out.println("狗"); 
        }else if(a instanceof Cat){ 
            System.out.println("猫"); 
        } 
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值