JAVA中extends 与implements有啥区别?

本文详细解析了Java中的extends和implements关键字的区别,包括它们的功能、用途、使用场景及注意事项,通过具体代码示例帮助理解接口的概念和实现方式。
 

JAVA中extends 与implements有啥区别?
1. 在类的声明中,通过关键字extends来创建一个类的子类。一个类通过关键字implements声明自己使用一个或者多个接口。
extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法; implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用
2.extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了
比如
class A extends B implements C,D,E

===========================================================
implements
学了好久,今天终于明白了implements,其实很简单,看下面几个例子就ok啦~~
接口的一些概念
public inerface Runner
{
   int ID = 1;
   void run ();
}


interface Animal extends Runner
{
   void breathe ();
}

 

class Fish implements Animal
{
   public void run ()
 {
    System.out.println("fish is swimming");
 }

public void breather()
 {
    System.out.println("fish is bubbing");   
 }
}

abstract LandAnimal implements Animal
{
  
   public void breather ()
 {
    System.out.println("LandAnimal is breathing");
 }
}
 
class Student extends Person implements Runner
{
    ......
    public void run ()
     {
          System.out.println("the student is running");
     }
    ......
}

 

interface Flyer
{
   void fly ();
}
 
class Bird implements Runner , Flyer
{
   public void run ()
    {
        System.out.println("the bird is running");
    }
   public void fly ()
    {
        System.out.println("the bird is flying");
    }
}
 

class TestFish
{
   public static void main (String args[])
    {
       Fish f = new Fish();
       int j = 0;
       j = Runner.ID;
       j = f.ID;
    }

}
接口实现的注意点:

a.实现一个接口就是要实现该接口的所有的方法(抽象类除外)。
b.接口中的方法都是抽象的。
c.多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。
 ===========================================================
extends与implements的不同

  extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了
比如
class A extends B implements C,D,E

//
    一个类通过关键字implements声明自己使用一个或者多个接口。在类的声明中,通过关键字extends来创建一个类的子类。
class 子类名 extends 父类名 implenments 接口名
{...

}
 
===========================================================

A a = new B(); 结果a是一个A类的实例,只能访问A中的方法,那么又和A a = new A();有什么区别呢?
==========================================================
class B extends A
继承过后通常会定义一些父类没有的成员或者方法。
A a = new B();
这样是可以的,上传。
a是一个父类对象的实例,因而不能访问子类定义的新成员或方法。
==========================================================
假如这样定义:
class A{
int i;
void f(){}
}
class B extends A{
int j;
void f(){}//重写
void g(){}
}
然后:
B b = new B();
b就是子类对象的实例,不仅能够访问自己的属性和方法,也能够访问父类的属性和方法。诸如b.i,b.j,b.f(),b.g()都是合法的。此时b.f()是访问的B中的f()
A a = new B();
a虽然是用的B的构造函数,但经过upcast,成为父类对象的实例,不能访问子类的属性和方法。a.i,a.f()是合法的,而a.j,a.g()非法。此时访问a.f()是访问B中的f()
==========================================================
A a = new B(); 这条语句,实际上有三个过程:
(1) A a;
将a声明为父类对象,只是一个引用,未分配空间
(2) B temp = new B();
通过B类的构造函数建立了一个B类对象的实例,也就是初始化
(3) a = (A)temp;
将子类对象temp转换未父类对象并赋给a,这就是上传(upcast),是安全的。
经过以上3个过程,a就彻底成为了一个A类的实例。
子类往往比父类有更多的属性和方法,上传只是舍弃,是安全的;而下传(downcast)有时会增加,通常是不安全的。
===========================================================
a.f()对应的应该是B类的方法f()
调用构造函数建立实例过后,对应方法的入口已经确定了。
如此以来,a虽被上传为A类,但其中重写的方法f()仍然是B的方法f()。也就是说,每个对象知道自己应该调用哪个方法。
A a1 = new B();
A a2 = new C();
a1,a2两个虽然都是A类对象,但各自的f()不同。这正是1楼说的多态性的体现。

这类问题在《Java编程思想》上都讲的很清楚

===========================================================

Java泛型主要分为以下几类,每种类型的使用方式和适用场景有所不同: ### 1. 泛型类(Generic Class) 泛型类是在定义类时使用类型参数,使得类可以适用于多种数据类型。通过泛型类,可以定义一个通用的数据结构,例如集合类或容器类。泛型类的类型参数在实例化时指定。 ```java public class Box<T> { private T item; public void setItem(T item) { this.item = item; } public T getItem() { return item; } } ``` 使用方式: ```java Box<String> stringBox = new Box<>(); stringBox.setItem("Hello"); String item = stringBox.getItem(); // 不需要强制类型转换 [^1] ``` ### 2. 泛型接口(Generic Interface) 泛型接口泛型类类似,用于定义通用的接口。例如,`java.util.List<T>` 接口就是一个泛型接口,它可以存储不同类型的元素。 ```java public interface Repository<T> { void add(T item); T get(int id); } ``` 实现方式: ```java public class StringRepository implements Repository<String> { // 实现方法 } ``` ### 3. 泛型方法(Generic Method) 泛型方法允许在方法中使用类型参数,而不必依赖于类或接口的泛型定义。泛型方法可以在泛型类或普通类中使用。 ```java public class Utility { public static <T> void printArray(T[] array) { for (T element : array) { System.out.println(element); } } } ``` 使用方式: ```java Integer[] intArray = {1, 2, 3}; Utility.printArray(intArray); // 传递 Integer 数组 [^2] ``` ### 4. 通配符(Wildcard) 通配符 `?` 是一种特殊的泛型参数,用于表示未知类型。它主要用于方法参数中,以增强灵活性。通配符分为以下几种形式: - **无界通配符**(Unbounded Wildcard):`List<?>` 表示可以接受任何类型的列表。 - **上界通配符**(Upper Bounded Wildcard):`List<? extends Number>` 表示可以接受 `Number` 或其子类的列表。 - **下界通配符**(Lower Bounded Wildcard):`List<? super Integer>` 表示可以接受 `Integer` 或其父类的列表。 示例: ```java public static void printList(List<?> list) { for (Object item : list) { System.out.println(item); } } ``` ### 5. 类型擦除(Type Erasure) Java 泛型是通过类型擦除来实现的,这意味着在编译后,泛型信息会被移除,所有泛型参数都会被替换为它们的上界(默认为 `Object`)。因此,运行时无法获取泛型的实际类型信息。 例如: ```java List<String> stringList = new ArrayList<>(); List<Integer> integerList = new ArrayList<>(); System.out.println(stringList.getClass() == integerList.getClass()); // 输出 true [^1] ``` ### 6. 泛型数组(Generic Arrays) Java 不支持直接创建泛型数组,因为类型擦除会导致运行时无法确定数组的类型。但可以通过其他方式实现类似功能。 ```java // 以下代码会导致编译错误 T[] array = new T[10]; // 可以通过传递 Class<T> 对象来创建数组 public <T> T[] createArray(Class<T> clazz, int size) { return (T[]) Array.newInstance(clazz, size); } ``` ### 7. 自限定类型(Self-Bounded Types) 自限定类型是一种特殊的泛型模式,其中类型参数被限制为当前类本身。这种模式常用于实现链式调用或构建器模式。 ```java public class Animal<T extends Animal<T>> { public T self() { return (T) this; } } public class Dog extends Animal<Dog> { // Dog 的具体实现 } ``` 使用方式: ```java Dog dog = new Dog(); Dog result = dog.self(); // 返回 Dog 类型 [^3] ``` ### 使用区别总结 - **泛型类** 和 **泛型接口**:用于定义通用的数据结构或接口,类型参数在实例化时指定。 - **泛型方法**:用于在方法中定义独立的类型参数,增强方法的灵活性。 - **通配符**:用于增强方法参数的灵活性,表示未知类型。 - **类型擦除**:Java 泛型的实现机制,导致运行时无法获取泛型信息。 - **泛型数组**:由于类型擦除,Java 不支持直接创建泛型数组。 - **自限定类型**:用于实现链式调用或构建器模式。 通过合理使用这些泛型特性,可以编写出更加灵活、类型安全的代码,同时避免强制类型转换带来的运行时错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值