zoukankan      html  css  js  c++  java
  • java面向对象封装、继承、多态、重写与重载

    封装

      在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。

    优点:

    • 良好的封装能够减少耦合。

    • 类内部的结构可以自由修改。

    • 可以对成员变量进行更精确的控制。

    • 隐藏信息,实现细节。

    步骤:

      1. 修改属性的可见性来限制对属性的访问(一般限制为private)

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

    //封装FZ_EncapTest类
    
    package com.company;
    
    public class FZ_EncapTest {
    
        private String name;
        private String idNum;
        private int age;
    
        public int getAge(){
            return age;
        }
    
        public String getName(){
            return name;
        }
    
        public String getIdNum(){
            return idNum;
        }
    
        public void setAge( int newAge){
            age = newAge;
        }
    
        public void setName(String newName){
            name = newName;
        }
    
        public void setIdNum( String newId){
            idNum = newId;
        }
    }
    FZ_EncapTest.java
    // 调用封装的FZ_EncapTest类
    package com.company;
    
    public class FZ_RunEncap{
        public static void main(String args[]){
            FZ_EncapTest encap = new FZ_EncapTest();
            encap.setName("James");
            encap.setAge(20);
            encap.setIdNum("12343ms");
    
            System.out.print("Name : " + encap.getName()+
                    " Age : "+ encap.getAge());
        }
    }
    
    
    /*
    Name : James Age : 20
    */
    FZ_ RunEncap.java

    继承

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

    类的继承格式

      通过 extends 关键字可以申明一个类是从另外一个类继承而来的

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

    继承关键字  

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

      implements:以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

    public interface A {
        public void eat();
        public void sleep();
    }
     
    public interface B {
        public void show();
    }
     
    public class C implements A,B {
    }

      super:通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

      this:指向自己的引用

    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 Test {
      public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        Dog d = new Dog();
        d.eatTest();
      }
    }
    
    
    /*
    animal : eat
    dog : eat
    animal : eat
    */
    Test.java

      final:可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写。

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

    构造器

      1、子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。

      2、如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

      3、果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

    class SuperClass {
      private int n;
      SuperClass(){
        System.out.println("SuperClass()");
      }
      SuperClass(int n) {
        System.out.println("SuperClass(int n)");
        this.n = n;
      }
    }
    // SubClass 类继承
    class SubClass extends SuperClass{
      private int n;
      
      SubClass(){ // 自动调用父类的无参数构造器
        System.out.println("SubClass");
      }  
      
      public SubClass(int n){ 
        super(300);  // 调用父类中带有参数的构造器
        System.out.println("SubClass(int n):"+n);
        this.n = n;
      }
    }
    // SubClass2 类继承
    class SubClass2 extends SuperClass{
      private int n;
      
      SubClass2(){
        super(300);  // 调用父类中带有参数的构造器
        System.out.println("SubClass2");
      }  
      
      public SubClass2(int n){ // 自动调用父类的无参数构造器
        System.out.println("SubClass2(int n):"+n);
        this.n = n;
      }
    }
    public class TestSuperSub{
      public static void main (String args[]){
        System.out.println("------SubClass 类继承------");
        SubClass sc1 = new SubClass();
        SubClass sc2 = new SubClass(100); 
        System.out.println("------SubClass2 类继承------");
        SubClass2 sc3 = new SubClass2();
        SubClass2 sc4 = new SubClass2(200); 
      }
    }
    
    
    
    /*
    ------SubClass 类继承------
    SuperClass()
    SubClass
    SuperClass(int n)
    SubClass(int n):100
    ------SubClass2 类继承------
    SuperClass(int n)
    SubClass2
    SuperClass()
    SubClass2(int n):200
    */
    TestSuperSub.java

     

    重写(Override)与重载(Overload)

    重写(Override)

      重写Override:子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

    重写规则

    • 参数列表与被重写方法的参数列表必须完全相同。
    • 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
    • 访问权限不能比父类中被重写的方法的访问权限更低。
    • 父类的成员方法只能被它的子类重写。
    • 声明为 final 的方法不能被重写。
    • 声明为 static 的方法不能被重写,但是能够被再次声明。
    • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
    • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
    • 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
    • 构造方法不能被重写。
    • 如果不能继承一个类,则不能重写该类的方法。
    class Animal{
       public void move(){
          System.out.println("动物可以移动");
       }
    }
     
    class Dog extends Animal{
       public void move(){
          super.move(); // 应用super类的方法,调用父类的move()方法
          System.out.println("狗可以跑和走");
       }
    }
     
    public class TestDog{
       public static void main(String args[]){
     
          Animal b = new Dog(); // Dog 对象
          b.move(); //执行 Dog类的方法
     
       }
    }
    
    
    /*
    动物可以移动
    狗可以跑和走
    */
    TestDog.java

    重载 (overload)

      重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

    重载规则:

    • 被重载的方法必须改变参数列表(参数个数或类型不一样);
    • 被重载的方法可以改变返回类型;
    • 被重载的方法可以改变访问修饰符;
    • 被重载的方法可以声明新的或更广的检查异常;
    • 方法能够在同一个类中或者在一个子类中被重载。
    • 无法以返回值类型作为重载函数的区分标准。
    public class Overloading {
        public int test(){
            System.out.println("test1");
            return 1;
        }
     
        public void test(int a){
            System.out.println("test2");
        }   
     
        //以下两个参数类型顺序不同
        public String test(int a,String s){
            System.out.println("test3");
            return "returntest3";
        }   
     
        public String test(String s,int a){
            System.out.println("test4");
            return "returntest4";
        }   
     
        public static void main(String[] args){
            Overloading o = new Overloading();
            System.out.println(o.test());
            o.test(1);
            System.out.println(o.test(1,"test3"));
            System.out.println(o.test("test4",1));
        }
    }
    
    
    /*
    test1
    1
    test2
    test3
    returntest3
    test4
    returntest4
    */
    Overloading.java

    重写与重载之间的区别

    区别点重载方法重写方法
    参数列表 必须修改 一定不能修改
    返回类型 可以修改 一定不能修改
    异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
    访问 可以修改 一定不能做更严格的限制(可以降低限制)

      总结:

        1.重写是在继承的时候发生,子类改写父类的方法。

        2.重载是在同一个类里,同名的方法不同的参数,通过参数的不同调用不同的方法。

    多态

      多态是同一个行为具有多个不同表现形式或形态的能力。就是同一个接口,使用不同的实例而执行不同操作

    多态的优点

    • 1. 消除类型之间的耦合关系
    • 2. 可替换性
    • 3. 可扩充性
    • 4. 接口性
    • 5. 灵活性
    • 6. 简化性

    多态存在的三个必要条件

    • 继承
    • 重写
    • 父类引用指向子类对象:Parent p = new Child();
    public class Test {
        public static void main(String[] args) {
          show(new Cat());  // 以 Cat 对象调用 show 方法
          show(new Dog());  // 以 Dog 对象调用 show 方法
                    
          Animal a = new Cat();  // 向上转型  
          a.eat();               // 调用的是 Cat 的 eat
          Cat c = (Cat)a;        // 向下转型  
          c.work();        // 调用的是 Cat 的 work
      }  
                
        public static void show(Animal a)  {
          a.eat();  
            // 类型判断
            if (a instanceof Cat)  {  // 猫做的事情 
                Cat c = (Cat)a;  
                c.work();  
            } else if (a instanceof Dog) { // 狗做的事情 
                Dog c = (Dog)a;  
                c.work();  
            }  
        }  
    }
     
    abstract class Animal {  
        abstract void eat();  
    }  
      
    class Cat extends Animal {  
        public void eat() {  
            System.out.println("吃鱼");  
        }  
        public void work() {  
            System.out.println("抓老鼠");  
        }  
    }  
      
    class Dog extends Animal {  
        public void eat() {  
            System.out.println("吃骨头");  
        }  
        public void work() {  
            System.out.println("看家");  
        }  
    }
    
    
    /*
    吃鱼
    抓老鼠
    吃骨头
    看家
    吃鱼
    抓老鼠
    */
    Test.java
  • 相关阅读:
    [bzoj4241] 历史研究 (分块)
    [tyvj2054] 四叶草魔杖 (最小生成树 状压dp)
    20180710 考试记录
    [luogu2047 NOI2007] 社交网络 (floyed最短路)
    [luogu2081 NOI2012] 迷失游乐园 (树形期望dp 基环树)
    [luogu1600 noip2016] 天天爱跑步 (树上差分)
    [luogu2216 HAOI2007] 理想的正方形 (2dST表 or 单调队列)
    [poj 3539] Elevator (同余类bfs)
    [BZOJ1999] 树网的核 [数据加强版] (树的直径)
    bzoj2301 [HAOI2011]Problem b
  • 原文地址:https://www.cnblogs.com/ppzhang/p/15662690.html
Copyright © 2011-2022 走看看