Java 三大特性

一、封装

定义

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

目的

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

封装的优点

  1. 良好的封装能够减少耦合。
  2. 类内部的结构可以自由修改。
  3. 可以对成员变量进行更精确的控制。
  4. 隐藏信息,实现细节。

实现

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

public class Person {
    private String name;//private封装属性
    private int age;
}

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

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

    public int getAge(){
      return age;
    }

    public String getName(){
      return name;
    }

    public void setAge(int age){
      this.age = age;
    }

    public void setName(String name){
      this.name = name;
    }
}

二、继承

定义

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

目的

  • 继承的出现提高了代码的复用性,提高软件开发效率。
  • 继承的出现让类与类之间产生了关系,提供了多态的前提。

类与类的3种关系:
is a :继承关系,例如:公共汽车 is a 汽车
use a:使用关系,例如:人 use a 钳子
has a:包含关系,例如:人has a 胳膊

实现

使用extends关键字

class 子类 extends 父类 {
    
}

案例:公司有2个部门,人事部和研发部,各自属性如下



定义部门类

/**
 * 部门父类:存放所有子类共性的内容
 */
public class Deparment {
    private int ID;// 部门编号
    private String name = "待定";// 部门名称
    private int amount = 0;// 部门人数
    private String responsibility = "待定";// 部门职责
    private String manager = "无名氏";// 部门经理
    
    省略了get和set

定义人事部

/**
 * 人事部
 */
public class PersonalDepartment extends Deparment{
    private int count;//招聘人数

    public PersonalDepartment() {
    }

    public PersonalDepartment(int count) {

        this.count = count;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

定义研发部

/**
 * 研发部
 */
public class ResourceDepartment extends Deparment{

    private String speciality =null;//研发方向

    public ResourceDepartment() {
    }

    public ResourceDepartment(String speciality) {
        this.speciality = speciality;
    }

    public String getSpeciality() {
        return speciality;
    }

    public void setSpeciality(String speciality) {
        this.speciality = speciality;
    }
}

测试公司类

/**
 * 公司类
 */
public class Company {
    public static void main(String[] args) {
        //创建人事部对象
        PersonalDepartment personalDepartment = new PersonalDepartment();
        //创建研发部对象
        ResourceDepartment resourceDepartment = new ResourceDepartment();
        //调用父类的方法
        System.out.println(personalDepartment.getName()); //getName()是父类的
        System.out.println(resourceDepartment.getName()); //getName()是父类的
    }
}

继承注意事项

类只支持单继承,不允许多继承
class A{} 
class B{}
class C extends A,B{}  // C类不可以同时继承A类和B类
多个类可以继承一个父类
class A{}
class B extends A{}
class C extends A{}   // 类B和类C都可以继承类A
允许多层继承
class A{}
class B extends A{}   // 类B继承类A,类B是类A的子类
class C extends B{}   // 类C继承类B,类C是类B的子类,同时也是类A的子类
子类和父类是一种相对概念

也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如上面的这种情况中,B类是A类的子类,同时又是C类的父类。

Object是所有类的父类

如果一个类没有显示定义父类,那么默认继承Object类

三、多态

定义

多态是同一个行为具有多个不同表现形式或形态的能力。同一个事件发生在不同的对象上会产生不同的结果。

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

实现

多态的实现方法有两种

  • 方法重写(公认的多态)
  • 方法重载(非公认的多态)

多态存在的三个必要条件
继承;重写;父类引用指向子类对象:Parent p = new Child();

普通类实现多态

  • 普通类多态定义的格式
父类 变量名 = new 子类();

例如:

class Fu {}
class Zi extends Fu {}
Fu f = new Zi();//类的多态使用

抽象类实现多态

  • 抽象类多态定义的格式
抽象类 变量名 = new 抽象类子类();

例如:

abstract class Fu {
     public abstract void method();
}
class Zi extends Fu {
    public void method(){
        System.out.println(“重写父类抽象方法”);
    }
}
Fu fu= new Zi();//类的多态使用

接口实现多态

  • 接口多态定义的格式
接口 变量名 = new 接口实现类();

例如:

interface Fu {
    public abstract void method();
}
class Zi implements Fu {
    public void method(){
         System.out.println(“重写接口抽象方法”);
    }
}
Fu fu = new Zi();//接口的多态使用
  • 注意事项

同一个父类的方法会被不同的子类重写。父类引用在调用方法时,调用的为各个子类重写后的方法。

Person p1 = new Student();
Person p2 = new Teacher();
p1.work(); //p1会调用Student类中重写的work方法
p2.work(); //p2会调用Teacher类中重写的work方法

当变量名指向不同的子类对象时,由于每个子类重写父类方法的内容不同,所以会调用不同的方法。

方法重载实现多态

class Student {
    public void doWork(){
        System.out.println(" is working ...");
    }
    public void doWork(Date from ,Date end){
        SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.println(" from "+ sdf.format(from) +"... end "+ sdf.format(end) +"... working....");
    }
}

public class TestInstanceof {
    public static void main(String[] args) {
        Student student = new Student();
        student.doWork();//第1种重载(第1种多态)
        student.doWork(new Date(1658972077239L),new Date(1658973187239L));//第2种重载(第2种多态)
    }
}

多态的转型

多态的转型分为向上转型与向下转型两种:

  • 向上转型就是父类引用指向子类对象
  • 向下转型就是子类引用指向父类对象

向上转型

向上转型:当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。
使用格式:

父类类型  变量名 = new 子类类型();

例如:

Person p = new Student();

向下转型

向下转型:一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。
如果是直接创建父类对象,是无法向下转型的!
使用格式:

子类类型 变量名 = (子类类型) 父类类型的变量;

例如

Student stu = (Student) p;  //变量p 实际上指向Student对象

多态的好处和弊端

当父类的引用指向子类对象时,就发生了向上转型,即把子类类型对象转成了父类类型。向上转型的好处是隐藏了子类类型,提高了代码的扩展性。
但向上转型也有弊端,只能使用父类共性的内容,而无法使用子类特有功能,功能有限制。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容