Java基础-封装、继承、多态

封装、继承、多态

面向对象三大特征:封装、继承、多态

一、 封装

  Java的封装其实是合理隐藏、合理暴露,隐藏即隐藏内部实现细节,暴露即向外界暴露“操作界面”,这样做,可以使一个实例的内部细节不会被破坏,又具有可操作性。

(1) 封装重点:访问控制符→private、默认(不写)、protected、public
 ① private:类访问权限,被它修饰的成员,只能在该类中被访问;
 ② 默认(不写):包访问权限,被它修饰的成员,只能在该类以及该类所在的包中被访问;
 ③ protected:子类访问权限,被它修饰的成员,只能在该类、该类所在的包以及其子类中被访问;
 ④ public:公共权限,被它修饰的成员,可在任意地方被访问;
MMSPicture
(2) 封装操作
 ① 将成员变量隐藏(private修饰);
 ② 为成员变量提供setter、getter方法(public修饰,setter方法有形参无返回值,getter方法无形参有返回值);
 ③ 需要暴露的方法用public修饰;
 ④ 如果希望一个方法主要用于被子类重写,用protected修饰;

(3) 封装示例:

class Worker {
    //实例变量
    private String name;
    private int age;
    private double salary;
    //setter、getter方法
    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;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public double getSalary() {
        return salary;
    }
    //暴露的方法
    public void live(String name,String words){
        System.out.println(name + " said: " + words);
    }
    //供子类重写的方法
    protected void working(String name,String job,int age){
        System.out.println("name:" + name + "," + "job:" + job + "," + "age:" + age);
    }
}
class WorkTest extends Worker{
	//重写Worker类中的working()方法
    @Override
    public void working(String name,String job,int age){
        age += new Random().nextInt(11);
        System.out.println("name:" + name + "," + "job:" + job + "," + "age:" + age);
    }
    public static void main(String[] args) {
        Worker w1 = new Worker();
        //操作Worker类中封装的成员变量
        w1.setName("Shakespeare");
        w1.setAge(900);
        w1.setSalary(500000.0);
        System.out.println("name:"+ w1.getName()+";"+"age:"+ w1.getAge()+";"+"salary:"+ w1.getSalary());
        //使用Worker类中暴露的live()方法
        w1.live(w1.getName(),"to be or not to be,that's a question");
        //使用WorkTest类中重写后的working()方法
        WorkTest w2 = new WorkTest();
        w2.working("Jack","painter",34);
    }
}

二、 继承

  Java的继承是类与类之间的关系(并不是对象和对象之间的关系) ,是一种由一般到特殊的关系,子类是一种特殊的父类。

(1) 继承要点:
 ① 关键字:extends[有扩展的意思,子类扩展了父类];
 ② 父类也叫超类、基类,子类也叫派生类;
 ③ 子类实例可以当做父类实例来使用,子类可获得父类的成员变量和方法;
 ④ Java是单继承,一个类只能有一个直接父类;
 ⑤ 所有类继承Object类;

(3) 继承示例:

class Human{
    protected String  name = "人类";
    protected int headnumber = 1;
    public void live(){
        System.out.println("使用工具");
    }
}
class Asian extends Human{
    public String skincolor = "黄色";
    public void smart(){
        System.out.println("聪明");
    }
}
class BlackPepple extends Human{
    public String skincolor = "黑色";
    public void dance(){
        System.out.println("善舞");
    }
}
class HumanTest{
    public static void main(String[] args) {
        Asian a1 = new Asian();
        BlackPepple b1 = new BlackPepple();
        //子类实例拥有父类的成员变量且可以有自己特有的变量[子类拥有父类的属性且可以拥有自己特有的属性]
        System.out.println("是" + a1.name + ",有" + a1.headnumber + "个脑袋" + ",肤色是" + a1.skincolor);
        System.out.println("是" + b1.name + ",有" + b1.headnumber + "个脑袋" + ",肤色是" + b1.skincolor);
        //子类实例拥有父类的方法且可以有自己特有的方法[子类拥有父类的“行为特征”且可以拥有自己特有的“行为特征”]
        a1.live();
        a1.smart();
        b1.live();
        b1.dance();
    }
}

三、 多态

  同一类型的多个实例、在执行同一个方法,呈现出多种行为特征叫多态。

(1) 多态示例:

class Bird {
   	protected String name = "鸟";
   	public void fly(){
   		System.out.println("鸟在天上飞~~~");
   	}
}						
class Sparrow extends Bird{
}					
class Ostrich extends Bird {
   	@Override
   	public void fly() {
   		System.out.println("鸵鸟只能跑~~~");
   	}
}			
public class BirdTest {
   	public static void main(String[] args) {
   		//子类对象赋值给父类变量
   		Bird b1 = new Sparrow();      
   		Bird b2 = new Ostrich();
   		//同一个类的多个实例b1、b2,执行同一个方法,输出结果不同
   		b1.fly();    //输出“鸟在天上飞~~~”       //动态绑定Sparrow类中的fly()方法,没有的话再向此类的父类中去寻找;
   		b2.fly();    //输出“鸵鸟只能跑~~~”       //动态绑定Ostrich类中的fly()方法,没有的话再向此类的父类中去寻找;
   		/**
         * 方法动态绑定:子类拥有父类的方法,子类实例调用某方法时若子类重写了该方法,优先使用子类自己重写的方法,若没有再去父类中寻找并使用
         */
   	}
}

(2) 多态下的特殊情况:

class Human{
    protected String  name = "人类";
    protected int headnumber = 1;
    public void live(){
        System.out.println("使用工具");
    }
}
class Asian extends Human{
    public String skincolor = "黄色";
    public void smart(){
        System.out.println("聪明");
    }
}
class BlackPepple extends Human{
    public String skincolor = "黑色";
    public void dance(){
        System.out.println("善舞");
    }
}
class HumanTest{
    public static void main(String[] args) {
    	//子类对象赋值给父类变量
        Human h1 = new Asian();
        h1.live();
        //h1.smart();    //----->此行编译报错
        /**
         * 问题:h1是new出来的Asian类的实例,Asian类中定义了smart()方法,为什么编译报错?
         */
    }
}

问题:以上代码中h1是new出来的Asian类的实例,Asian类中定义了smart()方法,为什么编译报错?
解释:一个变量在编译时,Java只认声明时指定的类型,h1在声明时指定的类型是Human,Human类中没有smart()方法,所以报错。
修改后如下:

class HumanTest{
    public static void main(String[] args) {
        //h1在声明时指定的类型是Asian类,它是Human的子类,那么h1可使用Human类中的live()方法,也可以使用Asian类中的smart()方法。
        Asian h1 = new Asian();
        h1.live();
        h1.smart();
        
        //声明时是Human类,只能调用Human类中的live()方法,这种情况强转成Asian类后才能使用Asian类中的smart()方法。
        Human h2 = new Asian();
        h2.live();
        Asian hh2 = (Asian) h2;
        hh2.smart();
        
    }
}

(3) 概念补充:
  衡量一个变量需考虑两种类型:编译时类型、运行时类型(实际类型)。编译时类型是指声明该变量时指定的类型,例如以上代码Human h2 = new Asian();变量h2的声明时类型为Human;运行时类型(实际类型)是指该变量实际所引用的对象的类型,那h2的运行时类型为Asian,Java程序在编译阶段只认编译时类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值