【新手向】从零开始学习Java(Day19)接口和包

每天二十分钟,成就Java大神,点点关注不迷路!

今天是第十九天,给坚持到这里的小伙伴点个赞!

梦想不曾坠落悬崖千钧一发,又怎会晓得执着的人拥有隐形翅膀,共勉!


目录

Java接口(Interface)

接口的特性

接口与类的相似点和区别

接口的声明

接口的实现

接口的继承

标记接口

Java包(package)

包的作用

创建包

例子-

方法一 java

方法二 javac + java(严格方法)

导入包(import关键字)

下节预告


Java接口(Interface)

      接口(Interface),在 Java 编程语言中是一个抽象类型是抽象方法的集合,接口通常以interface 来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法

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

      除非实现接口的类是抽象类,否则该类要定义接口中的所有方法

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

接口的特性

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

接口与类的相似点和区别

相似点:

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

区别:

  1. 接口不能用于实例化对象
  2. 接口没有构造方法
  3. 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法
  4. 接口不能包含成员变量除了 static 和 final 变量
  5. 接口不是被类继承了,而是要被类实现
  6. 接口支持多继承

抽象类和接口的区别:

  1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

接口的声明

接口的声明方式如下:

[访问控制运算符] interface 接口名称 [extends 其他的接口名] {
        // 声明静态变量
        // 抽象方法
}

上面提到,接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字;接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。

interface Animal {
   public void eat();
   public void travel();
}

接口的实现

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

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

public class MammalInt implements Animal{
 
   public void eat(){
      System.out.println("Mammal eats");
   }
 
   public void travel(){
      System.out.println("Mammal travels");
   } 
 
   public int noOfLegs(){
      return 0;
   }
 
   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

重写接口中声明的方法时,需要注意以下规则:

  1. 类在实现接口的方法时,不能抛出强制性异常只能在接口中,或者继承接口的抽象类中抛出该强制性异常
  2. 类在重写方法时要保持一致的方法名,并且应该保持相同或者相兼容的返回值类型。
  3. 如果实现接口的类是抽象类,那么就没必要实现该接口的方法

在实现接口的时候,也要注意一些规则:

  1. 一个类可以同时实现多个接口。
  2. 一个类只能继承一个类,但是能实现多个接口。
  3. 一个接口能继承另一个接口,这和类之间的继承比较相似。

接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。

非抽象类在实现接口时,应该将接口和其继承的接口的方法一起实现。

接口允许多继承,extends 关键字只需要使用一次,在其后可以跟着一个或多个继承接口。 

标记接口

标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。最常用的标记接口是没有包含任何方法的接口。

标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

  1. 建立一个公共的父接口:你可以使用一个标记接口来建立一组接口的父接口。
  2. 向一个类添加数据类型:这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

Java包(package)

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

包的作用

  1. 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用

  2. 如同文件夹一样,包也采用了树形目录的存储方式同一个包中的类名字是不同的不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突

  3. 包也限定了访问权限拥有包访问权限的类才能访问某个包中的类

创建包

创建包的时候,你需要为这个包取一个合适的名字。之后,如果其他的一个源文件包含了这个包提供的类、接口、枚举或者注释类型的时候,都必须将这个包的声明放在这个源文件的开头

包声明应该在源文件的第一行每个源文件只能有一个包声明,这个文件中的每个类型都应用于它

如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

  • 编译的时候,编译器为包中定义的每个类、接口等类型各创建一个不同的输出文件(即使两个类在同一个文件中),输出文件的名字就是这个类型的名字,并加上 .class 作为扩展后缀。
  • 并不要求 .class 文件的路径跟相应的 .java 的路径一样。你可以分开来安排源码和类的目录。这样,你可以将你的类目录分享给其他的编程人员,而不用透露自己的源码。用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到你程序中使用的所有类型。

例子-

这个例子创建了一个叫做animals的包。通常使用小写的字母来命名避免与类、接口名字的冲突:

首先创建一个文件夹,命名为animals,将这两份代码copy进去,编译运行:

package animals;
 
interface Animal {
   public void eat();
   public void travel();
}
package animals;

public class MammalInt implements Animal{
 
   public void eat(){
      System.out.println("Mammal eats");
   }
 
   public void travel(){
      System.out.println("Mammal travels");
   } 
 
   public int noOfLegs(){
      return 0;
   }
 
   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

这时候你会发现报错了:

因为当你使用 vscode 中的 runcode 插件运行程序时,他会默认进入到程序所在的目录,然后编译ManmmalInt.java 文件,这个文件有接口的实现,但是系统没有找到Animal(因为用户只让他运行ManmmalInt.java)。现在有两种解决方法:

方法一 java

在终端使用以下命令:

java MammalInt.java

隐式编译:当使用 java MammalInt.java 时,Java 会:

  1. 自动编译 MammalInt.java。

  2. 发现它依赖 Animal 接口,于是自动编译同目录下的文件 Animal.java 。

  3. 将所有编译后的类文件放在内存中临时目录,不污染源文件目录

这种方法适用于单个文件的临时调试时。

方法二 javac + java(严格方法)

必须在项目根目录中:

D:\Code\JAVA_learning\proj15

 然后输入下面两个命令:

# 编译指定包中的类
javac animals/MammalInt.java
# 运行
java animals.MammalInt

正式项目开发多使用这种方法。


导入包(import关键字)

为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。

import 关键字用于引入其他包中的类、接口或静态成员,它允许你在代码中直接使用其他包中的类,而不需要完整地指定类的包名

在 java 源文件中 import 语句必须在包声明之后(位于package 语句之后),类声明之前,其语法格式为:

import package1[.package2…].(classname|*);

可以使用 import语句来引入一个特定的类:

import animals.fish.Shark;// 引入 animals.fish 包中的 Shark 类

也可以使用通配符 * 来引入整个包或包的子包:

import animals.fish.*// 引入 animals.fish 包中的所有类

下节预告

下节开始,笔者将详细展开介绍 Java 中的枚举和反射,有疑惑可私信或评论区提出,and不妨动动发财的手点个赞吧,明天见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值