目录

--- 抽象类

--- 封装

抽象类:


在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。

由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。


定义:在Java语言中使用 abstract class 来定义抽象类。如下实例:

Employee.java - 抽象类

错误使用:直接使用抽象类,会出错,如下:

/* 文件名 : AbstractDemo.java */
public class AbstractDemo {
public static void main(String [] args) {
/* 以下是不允许的,会引发错误 */
Employee e = new Employee("George W.", "Houston, TX", ); System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}

当你尝试编译AbstractDemo类时,会产生如下错误(因为上述的 Employee.java 是抽象类):

Employee.java:: Employee is abstract; cannot be instantiated
Employee e = new Employee("George W.", "Houston, TX", );
^
error

正确使用:可以通过一般的方法继承 Employee 类:

/* 文件名 : Salary.java */
public class Salary extends Employee
{
private double salary; //Annual salary
public Salary(String name, String address, int number, double
salary)
{
super(name, address, number);
setSalary(salary);
}
public void mailCheck()
{
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName()
+ " with salary " + salary);
}
public double getSalary()
{
return salary;
}
public void setSalary(double newSalary)
{
if(newSalary >= 0.0)
{
salary = newSalary;
}
}
public double computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/;
}
}

继承抽象类 - Salary.java

从而,我们不能实例化一个 Employee 类(抽象类)的对象,但是如果我们实例化一个 Salary 类(继承抽象类的一般类)对象,该对象将从 Employee 类继承3个成员变量和7个成员方法。如下:实例化使用继承类 Salary:

/* 文件名 : AbstractDemo.java */
public class AbstractDemo
{
public static void main(String [] args)
{
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", , 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", , 2400.00); System.out.println("Call mailCheck using Salary reference --");
s.mailCheck(); System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}

使用继承类 - AbstractDemo.java


抽象类总结规定

  • 1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

  • 2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

  • 3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

  • 4. 构造方法,类方法(用static修饰的方法)不能声明为抽象方法。

  • 5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。


抽象方法:

如果你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类确定,那么你可以在父类中声明该方法为抽象方法。

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。示例:

public abstract class Employee{
private String name;
private String address;
private int number; public abstract double computePay(); // 声明 抽象方法 //其余代码
}

声明抽象方法会造成以下两个结果:

  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。eg:如果Salary类继承了Employee类,那么它必须实现computePay()方法:
    /* 文件名 : Salary.java */
    public class Salary extends Employee
    {
    private double salary; // Annual salary public double computePay()
    {
    System.out.println("Computing salary pay for " + getName());
    return salary/;
    } //其余代码
    }

Java 封装:

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

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

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

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

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

封装的优点:

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

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

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

  • 4. 隐藏信息,实现细节。


实现封装的步骤:

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

public class Person {
private String name;
private int age; //将 name 和 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; //采用 this 关键字是为了解决实例变量(private String name)和局部变量(setName(String name)中的name变量)之间发生的同名的冲突。
}

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

java封装类的实例:

/* 文件名: EncapTest.java */
public class 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;
}
} /*以上实例中 public方法 是外部类访问该类成员变量的入口。
通常情况下,这些方法被称为 getter 和 setter 方法。
因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。 */

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

/* 访问 封装类 中的 私有变量
* 文件名 : RunEncap.java */
public class RunEncap{
public static void main(String args[]){
EncapTest encap = new EncapTest();
encap.setName("James");
encap.setAge();
encap.setIdNum("12343ms"); System.out.print("Name : " + encap.getName()+
" Age : "+ encap.getAge());
}
}

上一篇:Java 学习(12):重写(Override)与重载(Overload) & 多态

下一篇:Java 学习(14):接口 & 包(设置 CLASSPATH 系统变量)

最新文章

  1. ios-深度解析二维码的生成与使用
  2. asp.net生成随机密码
  3. Android蓝牙实例(和单片机蓝牙模块通信)
  4. ajax form表单回显
  5. rsa加密--选择padding模式需要注意的问题。。。
  6. ubuntu网站做图像外链
  7. Asp.Net Webapi路由基本设置
  8. 转 OGG add trandata 到底做了什么
  9. (转)hadoop三个配置文件的参数含义说明
  10. KoaHub平台基于Node.js开发的Koa的get/set session插件代码详情
  11. html+css底部自动固定底部
  12. Javascript写的一个可拖拽排序的列表
  13. app锁定屏幕方向,某一个界面支持屏幕旋转~
  14. Golang闭包案例分析与普通函数对比
  15. RabbitMQ - Start Up
  16. jquery 通过attr获取属性只有一个值的解决
  17. Potree学习总结
  18. IOS8模糊毛玻璃的效果UIVisualEffectView
  19. java并发容器
  20. java 邮件发送工具类【来源网络自己已经实际应用】

热门文章

  1. 一入python深似海--python之道
  2. php冒泡排序函数
  3. JAVA输出带BOM的UTF-8编码的文件
  4. bzoj1934: [Shoi2007]Vote 善意的投票(显然最小割)
  5. 将ubuntu安装在用剩下的硬盘改装成的移动硬盘时遇到的问题及解决办法
  6. Java调用Python遇到的一系列问题与解决方案
  7. tf.nn.top_k(input, k, name=None)和tf.nn.in_top_k(predictions, targets, k, name=None)
  8. 【ICM Technex 2018 and Codeforces Round #463 (Div. 1 + Div. 2, combined) B】Recursive Queries
  9. 9 hbase源码系列(九)StoreFile存储格式
  10. hdu 1005 Number Sequence(矩阵连乘+二分快速求幂)