• 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;
            }    
        }
        
        
    }

      运行结果



  • 相关阅读:
    这次安装不太一样
    解惑C#不用释放内存(4)C#为何不用释放内存
    解惑C#不用释放内存(3)C++如何分配内存
    解惑C#不用释放内存(2)分配内存
    解惑C#不用释放内存(1)章节重点
    学习Java异常理解运行期异常
    学习Java声明异常throws
    学习java异常理解编译期异常
    学习java异常-前不久出现的问题
    学习java异常
  • 原文地址:https://www.cnblogs.com/wuxuewei/p/10950897.html
Copyright © 2020-2023  润新知