JAVA中方法的声明及使用方式(继承、多态、封装)

 更新时间:2024年02月06日 10:39:28   作者:小新的编程之路  
这篇文章主要介绍了JAVA中方法的声明及使用方式(继承、多态、封装),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、写在前面

今天就来总结一下JAVA中方法的声明及使用,即继承、多态、封装。

其实关于三大特性对于学习JAVA的同学来说都是基本的了,毕竟只要接触Java这些都是先要认识的,接下来就系统总结一下。

二、继承

先来说说继承,所谓继承本质就是实现代码的复用,防止重复的代码多次书写,当一个类继承一个类的时候,该类中就会拥有另外一个类中的所有代码

2.1 继承的注意事项

只支持单继承,即一个子类只允许有一个父类,但是可以实现多级继承,及子类拥有唯一的父类,而父类还可以再继承。

子类可以拥有父类的属性和方法。

子类可以拥有自己的属性和方法。

子类可以重写覆盖父类的方法。

2.2 继承的特点

  • 提高代码复用性。
  • 父类的属性方法可以用于子类。
  • 可以轻松的定义子类。
  • 使设计应用程序变得简单。

2.3 继承的使用

1,在父子类关系继承中,如果成员变量重名,则创建子类对象时,访问有两种方式。

a:直接通过子类对象访问成员变量

List item

等号左边是谁,就优先使用谁,如果没有就向上找。

b:间接通过成员方法访问成员变量

该方法属于谁,谁就优先使用,如果没有就向上找。

public class FU {
    int numFU = 10;
    int num = 100;
    public void method(){
        System.out.println("父类成员变量:"+numFU);
    }
    public void methodFU(){
        System.out.println("父类成员方法!");
    }
}
public class Zi extends FU{
    int numZi = 20;
    int num = 200;
    public void method(){
        System.out.println("子类成员变量:"+numFU);
    }
    public void methodZi(){
        System.out.println("子类方法!");
    }
}
public class ExtendDemo {
    public static void main(String[] args) {
        FU fu = new FU();
        // 父类的实体对象只能调用父类的成员变量
        System.out.println("父类:" + fu.numFU);   // 结果:10
        
        Zi zi = new Zi();
        System.out.println("调用父类:" + zi.numFU); // 结果:10
        System.out.println("子类:" + zi.numZi);   // 结果:20
 
        /** 输出结果为200,证明在重名情况下,如果子类中存在则优先使用,
         *  如果不存在则去父类查找,但如果父类也没有那么编译期就会报错。
         */
        System.out.println(zi.num); // 结果:200
        /**
         * 通过成员方法调用成员变量
         */
        zi.method();    // 结果:10
    }
}

2,同理:

​ 成员方法也是一样的,创建的对象是谁,就优先使用谁,如果没有则直接向上找。

​ 注意事项:

​ 无论是成员变量还是成员方法,如果没有都是向上父类中查找,绝对不会向下查找子类的。

3,在继承关系中,关于成员变量的使用:

  • 局部成员变量:直接使用
  • 本类成员变量:this.成员变量
  • 父类成员变量:super.父类成员变量
int numZi = 10;
 public void method() {
   int numMethod = 20;
   System.out.println(numMethod);  // 访问局部变量
   System.out.println(this.numZi); // 访问本类成员变量

2.4 重写和重载

2.4.1 重写(override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。

即外壳不变,核心重写!

class Animal{
   public void move(){
      System.out.println("动物行走!");
   }
}
 
class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
}
 
public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 对象
      Animal b = new Dog(); // Dog 对象
      a.move();// 执行 Animal 类的方法
      b.move();//执行 Dog 类的方法
   }
}

重写的规则:

1,参数列表必须与被重写方法相同。

2,访问权限不能比父类中被重写的方法的访问权限更低(public>protected>(default)>private)。

3,父类成员的方法只能被它的子类重写。

4,被final修饰的方法不能被重写。

5,构造方法不能

2.4.2 重载(overload)

重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

​ 最常用的地方就是构造器的重载。

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

重载规则:

1,被重载的方法必须改变参数列表(参数个数或者类型不一样)。

2,被重载的方法可以改变返回类型。

3,被重载的方法可以改变访问修饰符。

2.4.3 this,super关键字

super()关键字的用法:

  • 子类的成员方法中,访问父类的成员变量。
  • 子类的成员方法中,访问父类的成员方法。
  • 子类的构造方法中,访问父类的构造方法。

this关键字用法:

  • 本类成员方法中,访问本类的成员变量。
  • 本类成员方法中,访问本类的另一个成员方法。
  • 本类的构造方法中,访问本类的另一个构造方法。

​ 注意:

this关键字同super一样,必须在构造方法的第一个语句,且是唯一的。

this与super不能同时存在。

2.4.4 补充概念

隐藏

父类和子类拥有相同名字的属性或者方法( 方法隐藏只有一种形式,就是父类和子类存在相同的静态方法)时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。

隐藏是对于静态方法和成员变量(静态变量和实例变量)而言的

public class Animal {
    String name;
    int age;
    int legs;
    public void eat(){
        System.out.println("动物要吃饭");
    };
    //类方法,静态方法
    //通过类就可以直接调用
    public static void run(){
        System.out.println("动物在奔跑");
    }
}
public class Cat extends Animal {
    //重写父类方法
    public void eat() {
       System.out.println("小猫吃鱼");
    }
    //隐藏父类的run方法
    public static void run(){
        System.out.println("小猫在奔跑");
    }

}

对象转型

引用类型和对象类型不一致的情况下的转换问题

子类转父类(向上转型)

Animal a = new Animal();
Cat c = new Cat();
a = c;

一个很简单的判别办法,把右边的当做左边来用,看说得通不。右边c引用所指向的对象的类型是 猫

左边a引用的类型是 普通动物,把猫 当做 普通动物,说不说得通? 说得通,就可以转

父类转子类(向下转型)

父类转子类,有的时候行,有的时候不行,所以必须进行强制转换。强制转换的意思就是 转换有风险,风险自担。

可以的情况

Animal a = new Animal();
Cat c = new Cat();
a = c;
c = (Cat) a;
不可以的情况

Animal a = new Animal();
Cat c = new Cat();
Dog d = new Dog();
a = d;
c = (Cat) a;
没有继承关系的两个类,互相转换

没有继承关系的两个类,互相转换,一定会失败。

虽然Cat和Dog都继承了Animal,但是彼此没有互相继承关系

  • 实现类转换成接口(向上转型)
  • 接口转换成实现类(向下转型)

构造器

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

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

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

三、多态

3.1 定义和优点

定义:

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

优点:

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

3.2 多态的体现形式

继承父类引用指向子类重写

注意:在多态中,编译看左边,运行看右边

   public class MultiDemo {
       public static void main(String[] args) {
           // 多态的引用,就是向上转型
           Animals dog = new Dog();
           dog.eat();
           
           Animals cat = new Cat();
           cat.eat();
           
           // 如果要调用父类中没有的方法,则要向下转型
           Dog dogDown = (Dog)dog;
           dogDown.watchDoor();
   
       }
   }
   class Animals {
       public void eat(){
           System.out.println("动物吃饭!");
       }
   }
   class Dog extends Animals{
       public void eat(){
           System.out.println("狗在吃骨头!");
       }
       public void watchDoor(){
           System.out.println("狗看门!");
       }
   }
   class Cat extends Animals{
       public void eat(){
           System.out.println("猫在吃鱼!");
       }
   }

例如:

在设计房子时,大门的设计应该开进不同型号车辆,如打开一扇门,可以开进摩托车;打开两扇门,可以开进小汽车;如果需要,打开三扇门,允许开进货车等。

同样是门,由于不同参数,可以完成不同的功能,这个门具有多态性。

3.3 向上转型

  • 格式:父类名称 对象名 = new 子类名称(); 
  • 含义:右侧创建一个子类对象,把它当作父类来使用。
  • 注意:向上转型一定是安全的。
  • 缺点:一旦向上转型,子类中原本特有的方法就不能再被调用了。

四、封装

4.1 封装的特性

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

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问;要访问该类的代码和数据,必须通过严格的接口控制;封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段;适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。 

封装的特点

  • 对成员变量实行更准确的控制。
  • 封装可以隐藏内部程序实现的细节。
  • 良好的封装能够减少代码之间的耦合度。
  • 外部成员无法修改已封装好的程序代码。方便数据检查,有利于保护对象信息的完整性,同时也提高程序的安全性。便于修改,体高代码的可维护性。

4.2 封装的实现

使用private修饰符,表示最小的访问权限。

对成员变量的访问,统一提供setXXX,getXXX方法。

下面请看一个Student实体对象类:

public class Student implements Serializable {
    
    private Long id;
    private String name;
    private Integer sex;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Integer getSex() {
        return sex;
    }
 
    public void setSex(Integer sex) {
        this.sex = sex;
    }
}

分析:对于上面的一个实体对象,我想大家都已经很熟悉了。将对象中的成员变量进行私有化,外部程序是无法访问的。但是我们对外提供了访问的方式,就是set和get方法。

​ 而对于这样一个实体对象,外部程序只有赋值和获取值的权限,是无法对内部进行修改,因此我们还可以在内部进行一些逻辑上的判断等,来完成我们业务上的需要。

​ 到这里应该就明白封装对于我们的程序是多么重要。下面再来说说继承的那点事。

修改属性的可见性来限制对属性的访问(一般限制为private),例如

```java
public class People {
//将 name 和 age 属性设置为私有的,只能本类才能访问,其他类都访问不了,如此就对信息进行了隐藏。
    private String name;
    private int age;
}

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

public class People{
    //采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
    private String name;
    private int age;
​
    public String getName(){
        return name;
    }
​
  
    public void setName(String name){
        this.name = name;
    }
}

4.3 成员的访问权限

Java提供了三个访问控制符:private、protected和public,分别代表三个访问控制级别。

default访问控制权限(包访问权限)

如果类里的一个成员不使用任何访问控制符修饰,则使用default默认访问控制,default访问控制的成员可以被相同包下其他类访问。

protected访问控制权限(子类访问权限)

如果一个成员使用protected访问控制符修饰,那么这个成员即可以被同一包中其他类访问,也可以被不同包中的子类访问。

public访问控制权限(公共访问权限)

如果一个成员使用public访问控制符修饰,则可以被所有类访问。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用springboot开发的第一个web入门程序的实现

    使用springboot开发的第一个web入门程序的实现

    这篇文章主要介绍了使用springboot开发的第一个web入门程序的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 微信企业号验证/发送/接收消息

    微信企业号验证/发送/接收消息

    这篇文章主要介绍了微信企业号验证/发送/接收消息的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下
    2016-10-10
  • 手把手教你JAVA进制之间的转换

    手把手教你JAVA进制之间的转换

    这篇文章主要介绍了Java实现的进制转换,结合完整实例形式分析了Java实现二进制、十六进制、字符串、数组等相关转换操作技巧,需要的朋友可以参考下
    2021-08-08
  • SpringBoot实现application配置信息加密

    SpringBoot实现application配置信息加密

    在配置文件中,我们有开发环境配置和生产环境配置,而生产环境的配置信息是需要做好防护的,避免外泄,所以本文为大家整理了application配置信息加密的方法,需要的可以参考下
    2023-07-07
  • Java之网络编程案例讲解

    Java之网络编程案例讲解

    这篇文章主要介绍了Java之网络编程案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • java线程池ExecutorService超时处理小结

    java线程池ExecutorService超时处理小结

    使用ExecutorService时,设置子线程执行超时是一个常见需求,本文就来详细的介绍一下ExecutorService超时的三种方法,感兴趣的可以了解一下
    2024-09-09
  • JAVA找不到符号的三种解决方案

    JAVA找不到符号的三种解决方案

    这篇文章主要给大家介绍了关于JAVA找不到符号的三种解决方案, 找不到符号错误主要发生在我们试图引用一个未在我们正在编译的程序中声明的变量时,这意味着编译器不知道我们所引用的Java变量,需要的朋友可以参考下
    2024-03-03
  • Mybatis中的Criteria条件查询方式

    Mybatis中的Criteria条件查询方式

    这篇文章主要介绍了Mybatis中的Criteria条件查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • JavaWeb实现压缩多个文件并下载实例详解

    JavaWeb实现压缩多个文件并下载实例详解

    本文通过实例代码给大家讲解了javaweb实现压缩多个文件并下载功能,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-07-07
  • Java异步线程中的CompletableFuture与@Async详解

    Java异步线程中的CompletableFuture与@Async详解

    这篇文章主要介绍了Java异步线程中的CompletableFuture与@Async详解,CompletableFuture是java中提供的一个异步执行类,@Async是Spring提供的异步执行方法,当调用方法单独开启一个线程进行调用,需要的朋友可以参考下
    2024-01-01

最新评论