zoukankan      html  css  js  c++  java
  • (一)、面向对象特征:继承、封装、多态

    一、封装

      在面向对象设计方法中,封装(Encapsulation)是指一种将抽象性函数接口的实现细节部分包装、隐藏起来的方法,即屏蔽内部实现的细节,仅仅对外提供共有的方法/接口。

      封装可以被认为一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问

      要访问该类的代码和数据,必须通过严格的接口控制。

      封装最主要的功能在于我们能修改自己的实现代码,而不用修改哪些调用我们代码的程序片断。

      适当的封装可以让程序更容易理解与维护,也加强了程序的安全性。

    (一)实现封装的步骤

    1.修改属性的课件性来限制对属性的访问(一般为private),例如:

    public class Person{
        private String name;
        private int age;
    }

    这段代码中,将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。

    2.对每个值属性提供对外的公共访问,也就是创建一对赋值方法,用于对私有属性的访问,例如:

    /* 文件名:Test.java */
    public class Test{
        private String name;
        private int age;
    
        public int getAge(){
            return age;
        }
    
        public String getName(){
            return name;
        }
    
        public int setAge(int age){
            this.age = age;
        }
    
        public String setName(String name){
            this.name = name;
        }
    }

    采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。

    (二)实例

    一个java封装类的例子

    /* 文件名:Test.java */
    public class Test{
        private String name;
        private int age;
    
        public int getAge(){
            return age;
        }
    
        public String getName(){
            return name;
        }
    
        public void setAge(int newAge){
            age = newAge;
        }
    
        public void setName(String newName){
            name = newName;
        }
    }

    以上实例中public方法是外部类访问该类成员变量的入口。

    通常情况下,这些方法被称为getter和setter方法。

    因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。

    通过如下的例子说明Test类的变量怎样被访问:

    /* 文件名:Run.java */
    public class Run{
        public static void main(String[] args) {
            Test test = new Test();
            test.setName("leslie");
            test.setAge(20);
            System.out.println("Name : " + test.getName()
                + " Age : " + test.getAge());
        }
    }

    代码编译如下

    注:

    1.若一个类把自己的成员变量暴露给外部的时候,那么该类就失去对该成员变量的管理权,别人可以任意的修改你的成员变量。

    2.封装中经常使用@property(即setter和getter方法)

    3.在类的延展中对类进行分装,即:

      @interface NSObject()

      @end

    二、继承

    继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

    (一)类的继承格式

    在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:

    class 父类{
    
    }
    
    class 子类 extends 父类{
        
    }

    (二)继承类型

     Java 不支持多继承,但支持多重继承。

    (三)继承的特性

    1.子类拥有父类非private的属性、方法

    2.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展

    3.子类可以用自己的方式实现父类的方法

    4.Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,所以按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性

    5.提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)

    (四)继承的关键字

    1.extends关键字

    在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。

    public class Animal{
        private String name;
        private int id;
        public Animal(String myName, int myId){
            //初始化属性值
        }
        public void eat();
        public void sleep();
    }
    
    public class Pig extends Animal{
        
    }

    2.super与this关键字

    super关键字:

    super 表示使用它的类的父类。

      (1).调用父类的构造方法;

      super(); 或 super(参数列表);

      注意:静态方法中不能使用 super 关键字。

      (2).调用父类的方法(子类覆盖了父类的方法时);

      super.方法名(参数列表);

      如果是继承的方法,是没有必要使用 super 来调用,直接即可调用。

      但如果子类覆盖或重写了父类的方法,则只有使用 super 才能在子类中调用父类中的被重写的方法。

    this关键字:表示当前对象,即指向自己的引用

    /* 文件名:KeyTest */
    class Animal{
        void eat(){
            System.out.println("animal : eat");
        }
    }
    
    class Dog extends Animal{
        void eat(){
            System.out.println("dog : eat");
        }
        void eatTest(){
            this.eat(); //this 调用自己的方法
            super.eat(); //super 调用父类的方法
        }
    }
    
    public class KeyTest{
        public static void main(String[] args) {
            Animal a = new Animal();
            a.eat();
            Dog d = new Dog();
            d.eatTest();
        }
    }

    输出结果为

    3.final关键字

    final关键字声明类可以把类定义为不能继承的,即最终类;

    或者用于修饰方法,该方法不能被子类重写。

    声明类:

    final class 类名 {//类体}

    声明方法:

    修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

    注:实例变量也可以被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final。

    三、多态

    多态是指同一个行为具有多个不同表现形式或形态的能力。

    多态就是同一个接口,使用不同的实例而执行不同操作。

    如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。

    Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。

    Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

    多态体现为父类引用变量可以指向子类对象。 

    (一)多态的优点

    1.消除类型之间的耦合关系

    2.可替换性

    3.可扩充性

    4.接口性

    5.灵活性

    6.简化性

    (二)多态成员的特点

    1.多态成员变量:编译运行看左边

    Fu f = new Zi();
    System.out.println(f.num); //f是Fu中的值,只能取到夫中的值

    2.多态成员方法:编译看左边,运行看右边

    Fu f = new Zi();
    System.out.println(f.show()); //f的门面类型是Fu,但实际类型是Zi,所以调用的是重写后的方法。

    (三)instanceof关键字

    Java中,instanceof运算符的前一个操作符是一个引用变量,后一个操作数通常是一个类(可以是接口),用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是返回true,否则返回false。

    作用:用来判断某个对象是否属于某种数据类型。

    注意:返回类型是布尔型;instanceof 操作符的左右操作数必须有继承或实现关系

    Fu f1 = new Zi();
    Fu f2 = new Son();
    System.out.println(f1 instanceof Zi); //true
    System.out.println(f2 instanceof Zi); //false

    (四)多态的转型

    多态的转型分为向上转型和向下转型两种。

    1.向上转型:多态本身就是向上转型的过程

      使用格式:父类类型 变量名=new 子类类型();

      适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。

    2.向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型。

      适用格式:子类类型 变量名=(子类类型) 父类类型的变量;

      适用场景:当要使用子类特有功能时。

    (五)多态存在的三个必要条件

    继承、重写、父类引用指向子类对象

    比如:

    Parent p = new Child();

    当使用多态方法调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

    多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

    /* 文件名:Test.java */
    class People{  // 基本类作为父类,有一个基本方法
        public void eat(){
            System.out.println("吃饭");
        }
    }
    class Stu extends People{  //声明子类,继承父类,但有自己的方法(父类方法重写),并且实例化后优先使用自己的方法
        @Override
        public void eat(){
            System.out.println("吃水煮肉片");
        }
        public void study(){
            System.out.println("好好学习");
        }
    }
    class Teachers extends People{
        @Override
        public void eat(){
            System.out.println("吃樱桃");
        }
        public void teach(){
            System.out.println("认真授课");
        }
    }
    
    public class Test{
        public static void main(String[] args) {
            People p = new Stu(); //向上转型
            p.eat();
            //调用特有的方法
            Stu s = (Stu) p;     //向下转型
            s.study();
        }
    }

    输出结果为:

    很想高飞,但我不能;不想天空,剩我一人。
  • 相关阅读:
    系统文件夹路径的系统宏定义
    大数问题:用字符串解决大数相加和相乘
    C++中四种类型转换方式(ynamic_cast,const_cast,static_cast,reinterpret_cast)
    浅谈bitmap算法
    linux分享一:网络设置
    php分享十六:php读取大文件总结
    面试题一:linux面试题
    php分享十五:php的命令行操作
    查询系统负载信息 Linux 命令详解
    Linux守护进程
  • 原文地址:https://www.cnblogs.com/lixiansheng/p/11299693.html
Copyright © 2011-2022 走看看