Java是一门面向对象语言,可以看出“对象”在Java有着举足轻重的位置。那么,“对象”从何而来呢?那必须是丈母娘造出来的,下面我们就先来说说这个丈母娘——类。

Java类

  • 对象: 对象具有状态和行为。 例如:一只狗的状态有:颜色,名称,品种,它的行为有:摇尾巴,吠叫,吃东西。 对象是类的实例
  • 类: 类是一个模板,它描述一类具有相同状态和行为的对象。比如人类,都具有思考这个行为,而植物没有。

类可以看成是创建Java对象的模板,下面简单定义一个类:

public class People{
String name; // 成员变量
int age;
String weight;
static final double weeks = 9.5; // 类变量
void eat(){
} void sleep(){
} void play(){
} Public People {
// 这是一个构造方法
int count = 0; // 局部变量
}
}

一个类可以包含以下类型变量:

  • 局部变量: 在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁
  • 成员变量:成员变量定义在类中,方法体之外的变量。 这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问
  • 类变量:类变量也声明在类中,方法体之外,但必须声明为static类型
  • 类方法:概念同上面的类变量

构造方法

每个类都有构造方法。如果没有显示地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法

public class Puppy{
public Puppy(){
} public Puppy(String name){
// 这个构造器仅有一个参数:name
}
}

实例化对象

对象时根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:

  1. 声明:声明一个对象,包括对象名称和对象类型
  2. 实例化:使用关键字new来创建一个对象
  3. 初始化:使用new创建对象时,会调用构造方法初始化对象

下面是一个创建对象的例子:

public class Puppy{
public Puppy(String name){
//这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
} public static void main(String[] args){
// 下面的语句将创建一个Puppy对象
Puppy myPuppy = new Puppy( "tommy" );
}
}

编译并运行上面的程序,会打印出下面的结果:

小狗的名字是:tommy

下面的例子展示如何访问实例变量和调用成员方法:

public class Puppy{
int puppyAge;
public Puppy(String name){
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是 : " + name );
} public void setAge( int age ){
puppyAge = age; // 当形参`age`也是puppyAge时,需要用this:this.puppyAge = puppyAge
} public int getAge( ){
System.out.println("小狗的年龄为 : " + puppyAge );
return puppyAge;
} public static void main(String[] args){
/* 创建对象 */
Puppy myPuppy = new Puppy( "tommy" );
/* 通过方法来设定age */
myPuppy.setAge( 2 );
/* 调用另一个方法获取age */
myPuppy.getAge( );
/*你也可以像下面这样访问成员变量 */
System.out.println("变量值 : " + myPuppy.puppyAge );
}
}

编译并运行上面的程序,产生如下的结果:

小狗的名字是 : tommy
小狗的年龄为 : 2
变量值 : 2

Java继承

Java的继承是一种机制,表示为一个对象获取父对象的所有属性和行为

继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承(例如儿子继承父亲财产)类似。

Java中的继承,可以创建基于现有类构建新的类。 当你从现有类继承时,就可以重复使用父类的方法和字段,也可以在继承的新类中添加新的方法和字段。

为什么在Java中使用继承

对于方法覆盖(因此可以实现运行时的多态性),提高代码可重用性。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写(覆盖)。

Java类继承的语法示例:

class Super {
} class Sub extends Super {
}

extends关键字表示从现有类派生创建的新类。extends的含义是增加功能。在Java的术语中,被继承的类称为父类或超类,新类称为子类。

Java继承示例

如上图所示,Programmer是子类,Employee是超类。 两个类之间的关系是Programmer IS-A Employee. 它表示 Programmer 是一种 Employee 的类型。

参考下面示例代码实现:

class Employee {
float salary = 40000;
} class Programmer extends Employee {
int bonus = 10000; public static void main(String args[]) {
Programmer p = new Programmer();
System.out.println("Programmer salary is:" + p.salary);
System.out.println("Bonus of Programmer is:" + p.bonus);
}
}

执行上面代码得到以下结果:

Programmer salary is:40000.0
Bonus of programmer is:10000

在上面的例子中,Programmer对象可以访问自身类以及Employee类的字段,即提高了代码可重用性。

默认的: 不使用任何修饰符声明的属性和方法,对同一个包内的类是可见的。接口里的变量都隐式声明为public static final,而接口里的方法默认情况下访问权限为public

Java继承类型

在类的基础上,在Java中可以有三种类型的继承:单一,多级和分层继承。在Java的编程中,仅能通过接口支持多继承和混合继承。

注意:Java中的类不支持多继承

当一个类扩展多个类,即被称为多继承。例如:

问题:为什么在Java中不支持多继承?

为了降低复杂性并简化语言,Java中不支持多重继承。想象一个:ABC是三个类。 C类继承AB类。 如果AB类有相同的方法,并且从子类对象调用它,AB类的调用方法会有歧义。

因为编译时错误比运行时错误好,如果继承2个类,Java会在编译时报告错误。 所以无论子类中是否有相同的方法,都会有报告编译时错误。

注意:构造方法不能被继承,掌握这一点很重要。 一个类能得到构造方法,只有两个办法:编写构造方法,或者根本没有构造方法,类有一个默认的构造方法。

抽象类

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

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

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

抽象类

在Java中使用abstract关键字来定义抽象类。如下示例:

//example of abstract class that have method body
abstract class Bike {
Bike() {
System.out.println("bike is created");
} abstract void run(); void changeGear() {
System.out.println("gear changed");
}
} class Honda extends Bike {
void run() {
System.out.println("running safely..");
}
} class TestAbstraction2 {
public static void main(String args[]) {
Bike obj = new Honda();
obj.run();
obj.changeGear();
}
}

注意到该Bike类没有什么不同,尽管该类是抽象类,但是它仍然有成员变量,抽象方法,方法体,构造函数甚至main()方法。

执行上面的代码:

bike is created
running safely..
gear changed

抽象方法

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

Abstract 关键字同样可以用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体

抽象方法没有实现,方法名后面直接跟一个分号,而不是花括号。

public abstract class Employee
{
private String name;
private String address;
private int number; public abstract double computePay(); //其余代码
}

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

  • 如果一个类包含抽象方法,那么该类必须是抽象类
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类

继承抽象方法的子类必须重写该方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。

如果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/52;
} //其余代码
}

注意: 抽象类中不能有抽象构造方法或抽象静态方法

参考:Java抽象类

抽象类和类的区别

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

  • 抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以被实例化

  • 普通类和抽象类都可以被继承,但是抽象类被继承后子类必须重写继承的方法,除非自类也是抽象类

  • 抽象类中不一定含有抽象方法,但是有抽象方法的类必定时抽象类

  • 抽象类中的抽象方法只是声明,不包含方法体,即不能给出方法的具体实现

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

总之一句话,抽象类只是一种比较特殊的普通类。我觉得这篇文章解释的不错,大概意思就是:抽象类严格规定了几个你必须做的事情,比如:不能实例化、子类必须实现父类,除非子类也是抽象类。你不这样做就会出错,这种严谨的做法比人为规定的更加有效。

接口

定义:接口在Java中是一个抽象类型,是抽象方法的集合。一个类通过继承接口的方式,从而继承接口的抽象方法。

接口通常以interface来声明,可以看做是一种特殊的抽象类。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口的声明

接口的声明语法格式如下:

public interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}

接口有以下几个特征:

  • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
  • 接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final变量(并且只能是public,用private修饰会报编译错误)
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法

注:JDK 1.8 以后,接口里可以有静态方法和方法体

接口的实现

当类实现接口的时候,类要实现接口中的所有的方法。否则,类必须声明为抽象类

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

实现一个接口的语法,可以使用这个公式:

...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...

下面是一个Java的接口示例:

interface printable {
void print();
} class A6 implements printable {
public void print() {
System.out.println("Hello, Interface");
} public static void main(String args[]) {
A6 obj = new A6();
obj.print();
}
}

执行上面的代码,结果如下:

Hello,Interface

接口与类的相似点

  • 一个接口可以有很多方法
  • 接口文件保存在.java结尾的文件中,文件名使用接口名
  • 接口的字节码文件保存在.class结尾的文件中
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中

接口与类的区别

  • 接口不能用于实例化对象
  • 接口没有构造方法
  • 接口中所有方法必须为抽象方法
  • 接口不能包含成员变量,除了staticfinal变量
  • 接口不是被类继承了,而是要被类实现
  • 接口支持多继承

接口和抽象类的区别

  • 抽象类中的方法可以不是抽象方法,但接口中的方法必须都是抽象方法
  • 抽象类中的非抽象方法可以有方法体,就是实现方法的具体功能,避免在子类中重复实现这些方法。但接口中的方法不行(JDK 1.8以后可以有方法体,作为默认实现)
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的
  • 抽象类可以有具体的方法和属性, 接口只能有抽象方法和不可变常量(final)
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口
  • 抽象类里面的抽象方法必须全部被子类实现,如果子类不实现,那么子类必须也是抽象类。接口里面的方法也必须全部被子类实现,如果子类不能实现,那么子类必须是抽象类
  • 抽象类主要用来抽象类别,接口主要用来抽象方法功能。当你关注事物的本质的时候,请用抽象类;当你关注一种操作的时候,用接口
  • 抽离类可以实现接口,接口不能实现抽象类

参考:

抽象类和接口的区别

接口和抽象类有什么区别?

Java入门(一)——类、抽象类和接口的更多相关文章

  1. Java的Stack类实现List接口真的是个笑话吗

        今天在网上闲逛时看到了这样一个言论,说“Java的Stack类实现List接口的设计是个笑话”.   当然作者这篇文章的重点不是这个,原本我也只是一笑置之,然而看评论里居然还有人附和,说“Ja ...

  2. Java入门教程十(抽象类接口内部类匿名类)

    抽象类(abstract) 一个类只定义了一个为所有子类共享的一般形式,至于细节则交给每一个子类去实现,这种类没有任何具体的实例,只具有一些抽象的概念,那么这样的类称为抽象类. 在面向对象领域,抽象类 ...

  3. Java之继承、抽象类、接口篇

    一.继承(extends) 什么是继承? 继承是对现实生活中的"分类"概念的一种模拟. 狮子拥有动物的一切基本特性,但同时又拥有自己的独特的特性,这就是"继承" ...

  4. java提高篇(五)-----抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

  5. 十、Java基础---------面向对象之抽象类与接口

    抽象类(abstract)     当编写一个类时,时常会为该类定义一些方法,这些方法的使用用以描述该类的行为方式,那么这些方法都有具体的方法体.但是在某些情况下,某个父类只是知道子类应该包含怎样的方 ...

  6. Java中多态、抽象类和接口

    1:final关键字(掌握) (1)是最终的意思,可以修饰类,方法,变量. (2)特点: A:它修饰的类,不能被继承. B:它修饰的方法,不能被重写. C:它修饰的变量,是一个常量. (3)面试相关: ...

  7. Java学习日记-7 抽象类和接口

    一.抽象类 abstract修饰:类和类中的方法 抽象方法:abstract type name(parameter-list);(abstract不能修饰static方法和构造函数) 引用:抽象类有 ...

  8. (转)java提高篇(五)-----抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

  9. 【Java入门提高篇】Day2 接口

    上一篇讲完了抽象类,这一篇主要讲解比抽象类更加抽象的内容--接口. 什么是接口呢?先来看个栗子: /** * @author Frank * @create 2017/11/22 * @descrip ...

随机推荐

  1. vue项目中使用百度统计

    统计有多少人访问了自己的网站(wap端pc web端都适用),或者更细的统计网站每个页面的访问量,可以使用百度统计 百度统计传送门 按提示注册登录即可 登录后-->管理-->新增网站,配置 ...

  2. Maven入门【小白千万别点进】

    曾经有个女孩问我为什么要学Maven,我吧唧嘴就怼:Maven项目没有jar包它不香嘛,照样运行它不香嘛?如果让我一句话形容Maven,我会这样形容:"妈妈再也不用担心小明拿U盘去小红电脑里 ...

  3. [译]Nginx入门引导教程

    本文为[Beginner's Guide]译文,原文地址:http://nginx.org/en/docs/beginners_guide.html Guide 本教程基础的介绍了 nginx,以及能 ...

  4. vue 做一个简单的TodoList

    目录结构 index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  5. 2019/12/1 智能硬件实验室(ROS方向)

    浅谈安装ubuntu与ros感想 ubuntu 以前看电脑软件安装管家上的教程尝试在另一台电脑上安装ubuntu(虚拟机上),但是后面遇到了无法解决的问题,放弃了.这次因为选的ros方向,所以昨天在学 ...

  6. 并发编程--greenlet与gevent

    什么是greenlet? 虽然CPython(标准Python)能够通过生成器来实现协程,但使用起来还并不是很方便. 与此同时,Python的一个衍生版 Stackless Python实现了原生的协 ...

  7. 用IDCNN和CRF做端到端的中文实体识别

    实体识别和关系抽取是例如构建知识图谱等上层自然语言处理应用的基础.实体识别可以简单理解为一个序列标注问题:给定一个句子,为句子序列中的每一个字做标注.因为同是序列标注问题,除去实体识别之外,相同的技术 ...

  8. cesium定义线面

    面: var polygon = viewer.entities.add({ polygon : { hierarchy : { positions : null, holes : [{ positi ...

  9. CSS文字,文本常用样式

    CSS文字,文本常用样式 字体属性 font-family 如果电脑没有第一个字体,就切换到下一个 body { font-family: Microsoft YaHei,Helvetica,Aria ...

  10. 申请SSL证书

    1.为什么需要申请SSL证书呢? 因为之前公司网站是通过http访问的,现在要通过https方式访问,前面多了一个s,那就需要SSL证书,用https方式访问的,会加密用户上传和下载的数据,使访问更加 ...