Java入门(一)——类、抽象类和接口

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)
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口
  • 抽象类里面的抽象方法必须全部被子类实现,如果子类不实现,那么子类必须也是抽象类。接口里面的方法也必须全部被子类实现,如果子类不能实现,那么子类必须是抽象类
  • 抽象类主要用来抽象类别,接口主要用来抽象方法功能。当你关注事物的本质的时候,请用抽象类;当你关注一种操作的时候,用接口
  • 抽离类可以继承接口,接口不能继承抽象类(有待考究)

参考:

抽象类和接口的区别

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

原文地址:https://www.cnblogs.com/chenwenhao/p/12045786.html

时间: 2024-10-10 10:24:31

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

java面向对象编程(八)--抽象类、接口

1.抽象类 1.1抽象类概念 当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法[抽象方法],用abstract来修饰该类[抽象类]. //抽象类的必要性[Demo124.java] public class Demo124 { public static void main(String[] args) { //Animal an=new Animal();抽象类不允许实例化 Animal an=new Cat(); an.cry(); an=new Dog(); an.cr

Java语言中的----抽象类、接口

day12  Java语言中的抽象类与接口 一.抽象类和接口概述; 在昨天我们学习了Java的继承功能,这个是一个核心知识点,今天我们再继承的基础之上学习一下抽象类和接口这两个知识.什么是抽象类?如何定义一个抽象类?如何使用一个抽象类?这些都是我们需要掌握的. 同时我们还要知道如何来定义一个接口,在开发中定义接口来实现相关的功能是一个很重要的功能.如何来实现接口中的抽象方法,这些在这一节都会说到. 二.抽象类和接口 1.抽象类: 什么是抽象类?包含抽象方法的类就叫做抽象类 .使用abstract

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

今天在网上闲逛时看到了这样一个言论,说“Java的Stack类实现List接口的设计是个笑话”. 当然作者这篇文章的重点不是这个,原本我也只是一笑置之,然而看评论里居然还有人附和,说“Java那种Stack的设计作为笑话,差不多可以算公案了”,我就有点不淡定了,为什么.什么时候“作为笑话”的并且“差不多可以算公案”了呢? 因此我决定写一篇文章来谈谈这个问题. 接口是什么 狭义地讲,接口就是一个类所定义的方法(方法名.参数.返回值).一个类提供了Foo方法,其他类就可以调用它.广义上讲,接口可以理

Java基础5:抽象类和接口

Java基础5:抽象类和接口 1 抽象类一般会实现一部分操作,并且留一些抽象方法让子类自己实现,比如Stringbuffer和Stringbuilder的父类abstractStringbuilder. 2 接口一般指一种规定,比如一个map接口中,可能需要实现增删改查等功能,如果你想实现一个具体map,这些方法就必须按照规定去实现. 3 另外,一个类可以实现多个接口,但是不能继承多个类. 然而接口却可以继承多个其他接口.这一点很神奇. 下面看一下具体的例子,有一些小细节平时可能不会注意. cl

Java入门——Runtime类

Java入门——Runtime类 认识Runtime类 Runtime类表示运行时的操作类,是一个封装了JVM进程的类,每一个JVM都对应一个Runtime类的实例,此实例由JVM运行时为其实例化.取得Runtime类实例的方法为: Runtime run=Runtime.getRuntime(): 可以通过Runtime实例取得系统的一些信息 package Sep26; public class RuntimeDemo01 { public static void main(String[]

Java入门——System类

Java入门——System类 System类简介 System类是一些与系统相关的属性和方法的集合,而且所有属性都是静态的. 序号 方法定义 类型 描述 1 public static void exit(int static) 普通 系统退出,如果status为非0就表示退出 2 public static void gc() 普通 运行垃圾回收机制,调用的是Runtime类的gc()方法 3 public static long currentTimeMills() 普通 返回以毫秒为单位

Java入门——StringBuffer类

Java入门——StringBuffer类 认识StringBuffer类 如果一个字符串需要经常被改变,就需要使用StringBuffer类.(String类型的变量一旦声明就很难改变,若想改变,必须改变引用地址)! 字符串的连接操作 在程序书中使用append方法可以进行字符串的连接操作. package Sep22; public class StringBufferDemo01 { public static void main(String[] args) { StringBuffer

java基础2:抽象类、接口与多态

关于Java基础的文章,我觉得写得还可以,以前发在了我其它的博客了,肯定是原创,现在再分享给大家出来. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 一.抽象类 我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的.如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类.比如new Animal