zoukankan      html  css  js  c++  java
  • Java面向对象 第3节 类的封装和继承

     

    一、封装

    1. 封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的访问和操作。
    2. 封装的2个大致原则:
      1)把尽可能多的东西隐藏起来,对外提供便捷的接口
      2)把所有的属性隐藏起来
    3. 封装的实现:
      ◆JAVA定义了4种访问权限:public (公有的)、protected(保护的)、private(私有的)和默认的
      ◆封装步骤
      1)修改属性的可见性:设为private,防止错误修改
      2)创建getter/setter方法:用于属性的读写
      3)在getter/setter方法中加入属性控制语句:对属性值的合法性进行判断

        4.使用封装的好处:
        ◆便于使用者正确使用系统,防止错误修改属性
        ◆有助于系统之间的松耦合,提高系统独立性
        ◆提高软件的可重用性
        ◆降低了构建大型系统的风险
      

    package com.fengzhuang;
    /*
     *
     * @author yutianbao
     * @param
     * @date 2019/3/13 22:04
     * @return
     * @Motto: good good study,day day up
     */
    public class FengZhuang {
        /*封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过
        该类提供的方法来实现对隐藏信息的访问。*/
        // 实现封装分三步
        //1.修改属性的可见性:将属性私有化
        private String name;
        private int age;
        private String phoneNo;
    
        //2.创建setter/getter方法
        //给name赋值
        public String getName() {
            return this.name;
        }
        //取name值
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return this.age;
        }
        //3.添加对属性操制作的限制
        public void setAge(int age) {
            if(age>0&&age<=150){
                this.age = age;
            }else{
                System.out.println("您输入的年龄错误!");
                this.age = 25;
            }
        }
        public String getPhoneNo() {
            return this.phoneNo;
        }
        public void setPhoneNo(String phoneNo) {
            if(phoneNo.length()==11){
                this.phoneNo = phoneNo;
            }else{
                System.out.println("您输入的手机号错误!");
                this.phoneNo = "1xx xxxx xxxx" ;
            }
        }
        public void print(){
            System.out.println("我的名字是;"+this.getName()+",年龄是:"+this.getAge()+",手机号是:"+this.getPhoneNo());
        }
    
    }
    

      

    package com.fengzhuang;
    /*
     *
     * @author yutianbao
     * @param
     * @date 2019/3/13 22:08
     * @return
     * @Motto: good good study,day day up
     */
    public class Test {
        public static void main(String[] args){
            //FengZhuang fez = new FengZhuang("蒋辉煌",25,"18975742300");
            FengZhuang fez = new FengZhuang();
            fez.setName("余与");
            fez.setAge(160);
            fez.setPhoneNo("13632908564");
            fez.print();
        }
    
    } 

    二、继承 

      

    • 继承是一种由已有类创建新类的机制。利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类。新类继承一般类的状态和行为,并根据需要增加它自己的状态和行为。
    • 从现有类出发定义一个新类,称为新类继承了现有的类,其中被继承的现有类叫做超类(superclass)或父类,由继承而得到的类称为子类(subclass)。
    • Java中规定,一个父类可以同时拥有多个子类,但一个子类只能有一个父类,即单重继承,而且允许多层继承,即子类还可以有它自己的子类,在下一层的继承关系中原先的子类就变成了父类。这样的继承关系就形成了继承树。

      1、类继承用关键字extends实现,格式为:[访问权限修饰符]   class 子类名  extends 父类名{   子类的类体   }

         如果没有extends子句,则表示这个类直接继承Object,因为Java中所有的类都继承Object类。

      2、成员变量的继承

      子类继承父类中所有可被子类访问的成员变量。继承原则如下:

      2.1    能够继承那些声明为public和protected的成员变量。

      2.2    能够继承同一包中的那些默认修饰符的成员变量。

      2.3    不能继承那些声明为private的成员变量。

      2.4    如果子类声明一个与父类成员变量同名的成员变量,则不能继承父类的成员变量。此时子类的成员变量称做隐藏了父类的成员变量。

      总之,子类可继承父类的public、protected和默认修饰变量,不能继承private变量。反之,如果父类不允许其子类访问它的某些成员,那么它必须以private方式声明该成员。这一点充分体现了类封装的信息隐蔽原则。

      3、成员方法的继承

      子类继承成员方法的规则类似于继承成员变量的规则:子类继承父类中所有可被子类访问的成员方法。继承规则如下:

      3.1    能够继承那些声明为public和protected的成员方法。

      3.2    能够继承同一包中的默认修饰符的成员方法。

      3.3    不能继承那些声明为private的成员方法。

      3.4    不能继承父类的构造方法。

      如果子类方法与父类方法同名,则不能继承。子类方法称为覆盖(或重写)了父类中的那个方法。

      总之,子类可继承其父类的public、protected和默认修饰方法,不能继承private方法。子类除了可以继承父类中的变量及方法,还可以增加自己的成员。当一个父类成员不适合该子类时,子类会重新定义它,如果是重新定义的是成员变量就是隐藏父类的变量,如果是成员方法就是覆盖父类的方法。

    package com.extend;
    /**
     * 宠物类,狗狗和企鹅的父类
     */
    public class Pet {
    	private String name = "无名氏";// 昵称
    	private int health = 100;// 健康值
    	private int love = 20;// 亲密度
    
    	/**
    	 * 无参构造方法
    	 */
    	public Pet() {
    		System.out.println("父类无参构造方法");
    	}
    	/**
    	 * 有参构造方法
    	 * @param name  昵称
    	 */
    	public Pet(String name,int health,int love) {
    		this.name = name;
    		this.health = health;
    		this.love = love;
    		System.out.println("父类有参构造方法");
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getHealth() {
    		return health;
    	}
    
    	public void setHealth(int health) {
    		if(health<0||health>100){
    			System.out.println("健康值应该在0至100之间,默认值为60。");
    			this.health=60;
    			return;
    		}
    		this.health = health;
    	}
    
    	public int getLove() {
    		return love;
    	}
    
    
    
    	public void setLove(int love) {
    		if(love<0||love>100){
    			System.out.println("亲密度应该在0至100之间,默认值为10。");
    			this.love=10;
    			return;
    		}
    		this.love = love;
    	}
    
    	/**
    	 * 输出宠物信息
    	 */
    	public void print() {
    		System.out.println("宠物的自白:
    我的名字叫" +
    				this.name + ",我的健康值是" + this.health
    				+ ",我和主人的亲密程度是" + this.love + "。");
    	}
    
    	//重写Object类的equals()方法
    	public boolean equals(Object obj){
    		boolean flag = false;
    		if(obj==this){  //==比较引用地址
    			flag = true;
    		}
    		if(!(obj instanceof Pet)){  //instanceof  判断类型
    			flag = false;
    		}else{
    			Pet pe = (Pet)obj;
    			if(pe.love==this.love&&pe.health==this.health&&pe.love==this.love){
    				flag = true;
    			}
    		}
    		return flag;
    	}
    }
    

      

    package com.extend;
    /**
     * 狗狗类,宠物的子类
     */
    public class Dog extends Pet {
    	private String strain="哈士奇";// 品种
    
    	//无参构造方法
    	public Dog(String name,int health,int love,String strain) {
    		super(name,health,love);
    		this.strain = strain;
    		System.out.println("dog类构造方法");
    	}
    
    	public String getStrain() {
    		return strain;
    	}
    
    	public void setStrain(String strain) {
    		this.strain = strain;
    	}
    	//重写父类方法
    	public void print() {
    		System.out.println("宠物的自白:
    我的名字叫" +
    				this.getName() + ",我的品种是" + this.getStrain()+",我的健康值是" + this.getHealth()
    				+ ",我和主人的亲密程度是" + this.getLove() + "。");
    	}
    }
    

      

    package com.extend;
    
    import com.sun.jmx.snmp.SnmpString;
    
    /**
     * 企鹅类
     */
    public class Penguin extends Pet {
    	private String sex="Q仔";// 企鹅性别
    
    	//构造方法
    	public Penguin(String name,int health,int love,String sex) {
    		super(name,health,love);
    		this.sex = sex;
    		System.out.println("penguin类构造方法");
    	}
    
    	public String getSex() {
    		return sex;
    	}
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    	//重写父类方法
    	public void print() {
    		System.out.println("宠物的自白:
    我的名字叫" +
    				this.getName() + ",我的性别是" + this.getSex()+",我的健康值是" + this.getHealth()
    				+ ",我和主人的亲密程度是" + this.getLove() + "。");
    	}
    
    
    }
    

      

    package com.extend;
    //测试类
    public class Test {
    	public static void main(String[] args) {
    		// 1、创建宠物对象pet并输出信息
    		Pet pet = new Pet("贝贝",99,60);
    		//Pet pet1 = new Pet("贝贝",99,60);
    		//Pet pet2 = new Pet("贝贝",99,59);
    		//System.out.println("equals()比较对象:"+pet1.equals(pet2));
    		pet.print();
    		// 2、创建狗狗对象dog并输出信息
    		Dog dog = new Dog("贝贝",59,40,"牧羊犬");
    //		dog.setName("多多");
    //		dog.setHealth(90);
    //		dog.setLove(80);
    //		dog.setStrain("吉娃娃");
    		dog.print();
    		// 3、创建企鹅对象pgn并输出信息
    		Penguin pgn = new Penguin("幽幽",85,20,"Q妹");
    //		pgn.setName("大黑");
    //		pgn.setHealth(98);
    //		pgn.setLove(99);
    //		pgn.setSex("Q妹");
    		pgn.print();
    
    		/**************************/
    //		Bus bus = new Bus(20);
    //		bus.print();
    		//System.out.println(pgn.equals(dog));
    	}
    }
    

      4.子类访问父类成员  
      

      在数据隐藏和方法覆盖后,子类成员覆盖了父类的同名成员,要访问父类的这些成员,需用super关键字来引用当前类的父类。super的用法有3种情况:

      4.1  super.变量名:访问父类中被隐藏的成员变量。

           4.2  super.方法名([参数表]):调用父类中被重写的方法。

           4.3  super([参数表]):调用父类的构造方法,此时,可用super来表示父类的构造方法。

           例子可以参考上面继承的代码

           5.继承条件下的构造方法
      

    package com.extend;
    //测试类
    class Car{
    	private int siteNo = 4;//载客量
    	public Car(){
    		System.out.println("载客量是:"+siteNo+"人");
    	}
    	public void setSiteNo(int siteNo){
    		this.siteNo = siteNo;
    	}
    	public void print(){
    		System.out.println("载客量是:"+siteNo+"人");
    	}
    }
    class Bus extends Car{
    	 public Bus(int siteNo){
    		 setSiteNo(siteNo);
    	 }
    }
    public class Test {
    	public static void main(String[] args) {
                Bus bus = new Bus(20);
                bus.print();     
          }
    }    

      5、重写  

      ◆重写是指在继承过程中,子类中的成员(包括数据和方法)与其父类中的成员同名,但功能不同,此时,子类的成员“覆盖”从父类继承过来的成员。包括两种情况:

      一是数据覆盖,称为数据隐藏,即父、子类中数据成员的名称相同,类型不同,它们实际上是完全不同的两个数据;

      二是方法覆盖,称为方法重写,即父、子类中方法的名称相同,参数表也完全相同,但功能不同。

       

       ◆方法重写和方法重载的区别
       

          6.Object类的equals()方法    

       

  • 相关阅读:
    Linux里的2>&1究竟是什么
    表锁操作
    日志rsyslog
    计划任务at cron
    rpm包管理和源码包管理
    自建yum源(只演示nginx服务,其它都一样)
    软件包管理yum
    文件打包及压缩
    查找文件which locate find
    lsof恢复进程打开的文件
  • 原文地址:https://www.cnblogs.com/yutianbao/p/10502075.html
Copyright © 2011-2022 走看看