什么是封装?
封装只不过是保护任何容易改变的东西。封装背后的合理性是,如果任何功能被很好地封装在代码中,即只维护在一个地方而不是分散在代码中,那么很容易改变。这可以通过一个简单的 Java 封装示例来更好地解释。我们都知道构造函数用于在Java中创建对象,构造函数可以接受参数。假设我们有一个 Loan 类,它有一个构造函数,并且在各种类中,您使用这个构造函数创建了 Loan 的实例。现在要求发生了变化,您在贷款时还需要包括借款人的年龄。由于此代码没有很好地封装,即没有限制在一个地方,因此您需要在调用此构造函数的任何地方进行更改,即对于一次更改,您需要修改多个文件而不是一个更容易出错和乏味的文件,尽管它可以是如果您只需要在一个地方进行更改,那么高级IDE的重构功能会不会更好?是的,如果我们将 Loan 创建逻辑封装在一个方法中,比如 createLoan() 并且客户端代码调用此方法并且此方法在内部创建 Loan 对象,这是可能的。在这种情况下你只需要修改这个方法而不是所有的客户端代码。
示例
class Loan{
private int duration; //private variables examples of encapsulation
private String loan;
private String borrower;
private String salary;
//public constructor can break encapsulation instead use factory method
private Loan(int duration, String loan, String borrower, String salary){
this.duration = duration;
this.loan = loan;
this.borrower = borrower;
this.salary = salary;
}
//no argument consustructor omitted here
// create loan can encapsulate loan creation logic
public Loan createLoan(String loanType){
//processing based on loan type and than returning loan object
return loan;
}
}
在 Java 封装的同一个示例中,您会看到所有成员变量都是私有的,因此它们被很好地封装,您只能在此类中直接更改或访问该变量。如果您想允许外部世界访问这些变量,最好创建一个 getter 和 setter,例如getLoan() 允许您在归还贷款之前进行任何类型的验证、安全检查,因此它可以让您完全控制您想做的任何事情,并为受控和管理的客户提供单一访问渠道。
什么是抽象?
抽象类是不完整的东西,你不能创建抽象类的实例。如果你想使用它,你需要通过扩展它来使其完整或具体。如果一个类不包含任何抽象方法,并且实现了从它实现或扩展的抽象类或接口继承的所有抽象方法,则该类称为具体类。顺便说一句,Java 有抽象类的概念,抽象方法但变量在 Java 中不能是抽象的。 Java 中抽象类的流行示例是 ActionListener,它具有称为 actionPerformed(ActionEvent ae) 的抽象方法。当触发 ActionEvent 时调用此方法,例如单击 JButton 时。在java中通过使用匿名类实现抽象方法actionPerformed(ActionEvent ae)来将ActionListener附加到JButton中很常见,如下例所示:
JButton ok = new JButton("OK");
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
//code to handle event
}
});
在 Java 中,接口是另一种提供抽象的方式,接口默认是抽象的,只包含公共静态、最终常量或抽象方法。它非常常见的面试问题是,在我看来,我们应该在哪里使用抽象类以及我们应该在哪里使用 Java 接口,这对于设计更好的 Java 应用程序很重要,如果你只知道你的类的方法的名称,你就可以选择 java 接口应该有例如对于 Server 它应该有 start() 和 stop() 方法,但我们不知道这些 start 和 stop 方法将如何工作。如果您在设计类时知道一些行为,并且在所有子类中仍然很常见,请将其添加到抽象类中。像 Runnable 这样的接口是 Java 中抽象的一个很好的例子,用于抽象多线程执行的任务。