Java中抽象类和接口的区别
众所周知,抽象是指隐藏功能的内部实现,只向用户显示功能。即它的工作原理(显示),它是如何工作的(隐藏)。抽象类和接口都用于抽象,因此接口和抽象类是必需的先决条件
抽象类与接口
- 方法类型:接口只能有抽象方法。抽象类可以有抽象方法和非抽象方法。从Java 8 开始,它也可以有默认和静态方法。
- 最终变量: Java接口中声明的变量默认为最终变量。抽象类可能包含非最终变量。
- 变量类型:抽象类可以有最终、非最终、静态和非静态变量。该接口只有静态和最终变量。
- 实现:抽象类可以提供接口的实现。接口不能提供抽象类的实现。
- 继承与抽象: Java接口可以使用关键字“implements”来实现,抽象类可以使用关键字“extends”进行扩展。
- 多个实现:一个接口只能扩展另一个Java接口,一个抽象类可以扩展另一个Java类并实现多个Java接口。
- 数据成员的可访问性:默认情况下, Java接口的成员是公共的。 Java抽象类可以具有私有、受保护等类成员。
示例 1-A:
Java
// Java Program to Illustrate Concept of
// Abstract Class
// Importing required classes
import java.io.*;
// Class 1
// Helper abstract class
abstract class Shape {
// Declare fields
String objectName = " ";
// Constructor of this class
Shape(String name) { this.objectName = name; }
// Method
// Non-abstract methods
// Having as default implementation
public void moveTo(int x, int y)
{
System.out.println(this.objectName + " "
+ "has been moved to"
+ " x = " + x + " and y = " + y);
}
// Method 2
// Abstract methods which will be
// implemented by its subclass(es)
abstract public double area();
abstract public void draw();
}
// Class 2
// Helper class extending Class 1
class Rectangle extends Shape {
// Attributes of rectangle
int length, width;
// Constructor
Rectangle(int length, int width, String name)
{
// Super keyword refers to current instance itself
super(name);
// this keyword refers to current instance itself
this.length = length;
this.width = width;
}
// Method 1
// To draw rectangle
@Override public void draw()
{
System.out.println("Rectangle has been drawn ");
}
// Method 2
// To compute rectangle area
@Override public double area()
{
// Length * Breadth
return (double)(length * width);
}
}
// Class 3
// Helper class extending Class 1
class Circle extends Shape {
// Attributes of a Circle
double pi = 3.14;
int radius;
// Constructor
Circle(int radius, String name)
{
// Super keyword refers to parent class
super(name);
// This keyword refers to current instance itself
this.radius = radius;
}
// Method 1
// To draw circle
@Override public void draw()
{
// Print statement
System.out.println("Circle has been drawn ");
}
// Method 2
// To compute circle area
@Override public double area()
{
return (double)((pi * radius * radius));
}
}
// Class 4
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating the Object of Rectangle class
// and using shape class reference.
Shape rect = new Rectangle(2, 3, "Rectangle");
System.out.println("Area of rectangle: "
+ rect.area());
rect.moveTo(1, 2);
System.out.println(" ");
// Creating the Objects of circle class
Shape circle = new Circle(2, "Circle");
System.out.println("Area of circle: "
+ circle.area());
circle.moveTo(2, 4);
}
}
Java
// Java Program to Illustrate Concept of Interface
// Importing I/O classes
import java.io.*;
// Interface
interface Shape {
// Abstract method
void draw();
double area();
}
// Class 1
// Helper class
class Rectangle implements Shape {
int length, width;
// constructor
Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
@Override public void draw()
{
System.out.println("Rectangle has been drawn ");
}
@Override public double area()
{
return (double)(length * width);
}
}
// Class 2
// Helper class
class Circle implements Shape {
double pi = 3.14;
int radius;
// constructor
Circle(int radius) { this.radius = radius; }
@Override public void draw()
{
System.out.println("Circle has been drawn ");
}
@Override public double area()
{
return (double)((pi * radius * radius));
}
}
// Class 3
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating the Object of Rectangle class
// and using shape interface reference.
Shape rect = new Rectangle(2, 3);
System.out.println("Area of rectangle: "
+ rect.area());
// Creating the Objects of circle class
Shape circle = new Circle(2);
System.out.println("Area of circle: "
+ circle.area());
}
}
输出
Area of rectangle: 6.0
Rectangle has been moved to x = 1 and y = 2
Area of circle: 12.56
Circle has been moved to x = 2 and y = 4
如果我们在矩形和圆形之间没有任何共同的代码怎么办,然后使用界面。
示例 1-B:
Java
// Java Program to Illustrate Concept of Interface
// Importing I/O classes
import java.io.*;
// Interface
interface Shape {
// Abstract method
void draw();
double area();
}
// Class 1
// Helper class
class Rectangle implements Shape {
int length, width;
// constructor
Rectangle(int length, int width)
{
this.length = length;
this.width = width;
}
@Override public void draw()
{
System.out.println("Rectangle has been drawn ");
}
@Override public double area()
{
return (double)(length * width);
}
}
// Class 2
// Helper class
class Circle implements Shape {
double pi = 3.14;
int radius;
// constructor
Circle(int radius) { this.radius = radius; }
@Override public void draw()
{
System.out.println("Circle has been drawn ");
}
@Override public double area()
{
return (double)((pi * radius * radius));
}
}
// Class 3
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating the Object of Rectangle class
// and using shape interface reference.
Shape rect = new Rectangle(2, 3);
System.out.println("Area of rectangle: "
+ rect.area());
// Creating the Objects of circle class
Shape circle = new Circle(2);
System.out.println("Area of circle: "
+ circle.area());
}
}
输出
Area of rectangle: 6.0
Area of circle: 12.56
什么时候用什么?
如果这些陈述中的任何一个适用于您的情况,请考虑使用抽象类:
- 在Java应用程序中,有一些相关的类需要共享一些代码行,那么您可以将这些代码行放在抽象类中,这个抽象类应该由所有这些相关类扩展。
- 您可以在抽象类中定义非静态或非最终字段,以便通过方法访问和修改它们所属对象的状态。
- 您可以期望扩展抽象类的类具有许多公共方法或字段,或者需要公共以外的访问修饰符(例如受保护和私有)。
如果这些陈述中的任何一个适用于您的情况,请考虑使用接口:
- 它是完全抽象的,接口中声明的所有方法都必须由实现该接口的类来实现。
- 一个类可以实现多个接口。它被称为多重继承。
- 您想指定特定数据类型的行为,但不关心谁实现了它的行为。
您也可以参加有关此主题的测验。