Java初学——面向对象的封装,继承,多态

一、封装

  1.为什要封装

    封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。把尽可能多的东西藏起来,对外提供便捷的接口。

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

    封装的流程:

             :

  2.如何使用封装

    在myexclipse中在已经建好的类中,按住快捷键Shift+Alt+S选择R 在弹出面板中选择要封装的成员变量。具体流程如图:

  快捷键 Shift+Alt+S会出现如下图弹出界面 然后点击R

选择要封装的选项

点击ok,会生成get/set方法如图

或则选择myexlipse的工具栏Scoure---

 

二、继承

  1.继承的相关属性

      (1)在Java所有类都默认继承自Object,extends关键字实现类的继承。

    (2)单根性:一个类只能存在一个父类在Java中的继承:子类可以继承父类的任何非私有成员(变量 方法 构造) 子类永远比父类拥有更多的成员,子>父。提升代码的复用性:减少代码的冗余

    (3) Object:任意一个类都直接或间接继承Object 在MyEclipse中查看继承架构图的快捷键为ctrl+T ctrl+O 查看类中的所有成员 

    (4)native:不是由java实现的,而是由C语言实现的。

    (5)final:常量 类(代表该类不能被继承) 方法(该方法不能被子类重写) 。

    (6)方法重写:子类继承了父类的方法后,要对父类的方法进行改写 要求除了方法体之外,其他的必须一致(就进原则)。

    (7)super:超类 super代表父类的对象。使用super关键字,super代表父类对象 ;在子类构造方法中调用且必须是第一句 ;不可以访问父类中定义为private的属性和方法如图:                                                                                                                                                                                                 

  2.继承条件下构造方法的调用规则

    子类构造方法没有通过super显式调用父类的有参构造方法,也没通过this显式调用自身其他构造方法 系统默认调用父类的无参构造方法 子类构造方法通过super显式调用父类的有参构造方法 执行父类相应构造方法,而不执行父类无参构造方法 子类构造方法通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则

  3.子类能继承什么

    能继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里 继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里。

    不能继承父类中private成员,当子类与父类不在同包, 使用默认访问权限的成员。不能继承父类的构造方法。

   

 三、多态

  1.什么是多态

    发生在具有继承关系的实体中,不同实体为了完成同一操作(函数名)所采取的不同方式(方法体)。在子类中方法重写:除方法体之外。其余完全一致

 方法的重写或方法的覆盖:子类根据需求对从父类继承的方法进行重新编写 重写时,可以用super.方法的方式来保留父类的方法 构造方法不能被重写

  2.方法重写是多态的基础

    方法重写的规则:方法名相同 参数列表相同 返回值类型相同或者是其子类 访问权限不能严于父类 父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法 子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super) 父类的私有方法不能被子类覆盖 不能抛出比父类方法更多的异常。

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

  3.面相对象设计八大原则

    开-闭原则(目标、总的指导思想)对扩展开放,对修改关闭。增加新功能,不改变原有代码。

    类的单一职责(一个类的定义)一个类有且只有一个改变它的原因。适用于基础类,不适用基于基础类构建复杂的聚合类。

    依赖倒置(依赖抽象)客户端代码(调用的类)尽量依赖(使用)抽象的组件。抽象的是稳定的。实现是多变的。

    组合复用原则(复用的最佳实践)如果仅仅为了代码复用优先选择组合复用,而非继承复用。组合的耦合性相对继承低。

    里氏替换(继承后的重写,指导继承的设计)父类出现的地方可以被子类替换,在替换后依然保持原功能。 子类要拥有父类的所有功能。子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。

    接口隔离(功能拆分) 尽量定义小而精的接口interface,少定义大而全的接口。本质与单一职责相同。小接口之间功能隔离,实现类需要多个功能时可以选择多实现.或接口之间做继承。

    面向接口编程而非面向实现(切换、并行开发)客户端通过一系列抽象操作实例,而无需关注具体类型。便于灵活切换一系列功能。

    迪米特法则(类与类交互的原则)类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度

  4.多态实现的三种方式

     父类类型接收子类对象实现的多态
     父类类型作为方法形参
     父类类型作为方法返回值

  5.继承关系的引用数据类型转换     

    向上转型:子类对象--->父类做的转换 无需强转(没有异常)理论上和数据类型的强转和自转类似,向上转型就像int类型向double自动转形一样,子类本身会继承父类所有的非私有的成员变量和方法,并且还有自己的成员。所以子类转向父类是自动转换。

  
    向下转型:父类类型--->子类类型转换 需要强转当父类向子类转换时有可能会运行报错,所以应用instanceof关 键词来规避如果能转换则会返回true,不能返回false。

  6综合练习

    以下代码运用抽象类 继承  封装 多态 类型转换 做的简单电子宠物购物系统(代码只是用于知识点的串联)

    创建Pet父类

      

 1 public abstract class Pet {
 2     private String name;//名字
 3     private String sex;//性别
 4     private int heathly;//健康值
 5     private int qinmidu;//亲密度
 6     abstract String leibieString(int i);    //创建品种判断抽象方法
 7     abstract void showinfo() ;//创建自我介绍抽象方法
 8     abstract int zhiliao();//创建宠物治疗方法 让狗每次治疗健康值加十 企鹅每次治疗加5
 9     //封装
10     public String getName() {
11         return name;
12     }
13     public void setName(String name) {
14         this.name = name;
15     }
16     public String getSex() {
17         return sex;
18     }
19     public void setSex(String sex) {
20         this.sex = sex;
21     }
22     public int getHeathly() {
23         return heathly;
24     }
25     
26     public void setHeathly(int heathly) {
27         if (heathly<=100&&heathly>=0) {
28             this.heathly=heathly;
29         }else {
30             this.heathly=60;
31         }
32     }
33 
34     public int getQinmidu() {
35         return qinmidu;
36     }
37 
38     public void setQinmidu(int qinmidu) {
39         if (qinmidu<=100&&qinmidu>=0) {
40             this.qinmidu=qinmidu;
41         }else {
42             this.qinmidu=60;
43         }
44     }
45 
46     
47     
48 }

  创建子类dog

    

public class Dog extends Pet {

    private String leibie;
    public String getLeibie() {
        return leibie;
    }
    public void setLeibie(String leibie) {
        this.leibie = leibie;
    }
    //实例化抽象方法
    @Override
    String leibieString(int i) {
        leibie=(i==1?"哈士奇":i==2?"京巴":"输入序号错误,请从新输入");
        return leibie;    
    }
    @Override
    void showinfo() {
        System.out.println("你好主人:我叫"+super.getName()+"我是:"+ super.getSex()+"我的健康值是:"
    +super.getHeathly()+"和主人的亲密度为"+super.getQinmidu()+"我的品种是"+this.getLeibie());
    }
    @Override
    int zhiliao() {
        return (super.getHeathly()+10);
    }
    public void play(){
        System.out.println("经过强制转换我学会接飞镖");
    }
}

    创建Qie类

    

public class Qie extends Pet {
    private String leibie;
    public String getLeibie() {
        return leibie;
    }

    public void setLeibie(String leibie) {
        this.leibie = leibie;
    }

    @Override
    String leibieString(int i) {
        leibie=(i==1?"帝企鹅":i==2?"马达加斯加企鹅":"你的输入有误");
        return leibie;
    }

    @Override
    void showinfo() {
        System.out.println("你好主人:我叫"+super.getName()+"我是:"+ super.getSex()+"我的健康值是:"
                +super.getHeathly()+"和主人的亲密度为"+super.getQinmidu()+"我的品种是"+this.getLeibie());
    }

    @Override
    int zhiliao() {
        
        return (super.getHeathly()+5);
    }
    public  void eat() {
        System.out.println("经过了强制转换我会吃鱼");
    }

}

    创建测试类

    

import java.util.Scanner;

import com.sun.org.apache.bcel.internal.generic.INSTANCEOF;


public class Pettest {
    public static void main(String[] args) {
        String ii;
        int i;
        Scanner inScanner=new Scanner(System.in);
        System.out.println("欢迎来到宠物医院!");
        System.out.print("您的宠物种类是(1.狗狗2.企鹅)");
        int q=inScanner.nextInt();
        switch (q) {
        case 1:
            Dog a=new Dog();
            System.out.println("你的宠物名字是:");
             ii=inScanner.next();
            a.setName(ii);
            System.out.println("请输入性别(1.靓仔2.辣妹)");
             i=inScanner.nextInt();
            if(i==1){
                    a.setSex("靓仔");
                }else if(i==2){
                    a.setSex("辣妹");
                }else {
                    System.out.println("性别输入错误请从新输入");
                    i=inScanner.nextInt();
                }
            System.out.println("请选择品种1.哈士奇2.京巴");
            i=inScanner.nextInt();
            a.leibieString(i);
            System.out.println("请输入健康值");
            i=inScanner.nextInt();
            a.setHeathly(i);
            System.out.println("请输入亲密度");
            i=inScanner.nextInt();
            a.setQinmidu(i);
            a.showinfo();
            
            System.out.println("经过治疗你的狗狗健康值为"+a.zhiliao());
//            Pet bPet=new Dog();
//            Dog d=(Dog)bPet;
//            d.play();
            Pet bPet=new Dog();
            //强制装换
            if ( bPet instanceof Dog ) {
                
                Dog d=(Dog)bPet;
                d.play();
            }
            
            
            break;

        case 2:
            Qie aa=new Qie();
            System.out.println("你的宠物名字是:");
             ii=inScanner.next();
            aa.setName(ii);
            System.out.println("请输入性别(1.靓仔2.辣妹)");
             i=inScanner.nextInt();
            if(i==1){
                    aa.setSex("靓仔");
                }else if(i==2){
                    aa.setSex("辣妹");
                }else {
                    System.out.println("性别输入错误请从新输入");
                    i=inScanner.nextInt();
                }
            System.out.println("请选择品种1.帝企鹅2.马达加斯加企鹅");
            i=inScanner.nextInt();
            aa.leibieString(i);
            System.out.println("请输入健康值");
            i=inScanner.nextInt();
            aa.setHeathly(i);
            System.out.println("请输入亲密度");
            i=inScanner.nextInt();
            aa.setQinmidu(i);
            aa.showinfo();
            
            System.out.println("经过治疗你的"+aa.getLeibie()+"健康值为"+aa.zhiliao());
            Pet bQPet=new Qie();
            //强制装换
            if ( bQPet instanceof Qie ) {
                
                Qie dD=(Qie)bQPet;
                dD.eat();
            }
            
            break;
            default:
                System.out.println("您的输入有误请从新输入");
                break;
        }    
    }
    
    
}

  运行结果



原文地址:https://www.cnblogs.com/wuxuewei/p/10950897.html