Lớp trừu tượng trong Java


272

Một "lớp trừu tượng" trong Java là gì?


34
+1 Câu hỏi này rất cơ bản và cơ bản, nó là một câu hỏi kinh điển cho SO. Tôi ngạc nhiên vì nó đã không được hỏi ở đây trước đây.
Yuval

6
-1 cho nhận xét của Clement (nếu tôi có thể); lmgtfy không phải là một câu trả lời hữu ích. Về lý do, hãy đọc, ví dụ như meta.stackexchange.com/questions/5280/embrace-the-non-googlers
Jonik

26
@tuergeist. Sẽ không liên quan nếu nó dễ dàng với Google, miễn là nó chưa được hỏi về SO trước đó. Ngoài ra, ai nói câu hỏi mới bắt đầu về ngôn ngữ lập trình không thuộc về SO?
Jonik

12
Một điều tôi thích về SO là bạn sẽ nhận được một câu trả lời cô đọng, đúng đắn và đến mức mà không có bất kỳ BS thông thường nào tìm thấy trên phần còn lại của web ... Dù sao thì, cũng giống như vậy. +1 cho câu hỏi!
Anders Hansson

1
SO không chỉ cần có đuôi dài! J & J thậm chí còn nói về điều này xung quanh podcast 56 ...
kwutchak

Câu trả lời:


341

Một lớp trừu tượng là một lớp không thể khởi tạo được. Một lớp trừu tượng được sử dụng bằng cách tạo một lớp con kế thừa có thể được khởi tạo. Một lớp trừu tượng thực hiện một số điều cho lớp con kế thừa:

  1. Xác định các phương thức có thể được sử dụng bởi lớp con kế thừa.
  2. Xác định các phương thức trừu tượng mà lớp con kế thừa phải thực hiện.
  3. Cung cấp một giao diện chung cho phép lớp con được hoán đổi với tất cả các lớp con khác.

Đây là một ví dụ:

abstract public class AbstractClass
{
    abstract public void abstractMethod();
    public void implementedMethod() { System.out.print("implementedMethod()"); }
    final public void finalMethod() { System.out.print("finalMethod()"); }
}

Lưu ý rằng "trừu tượng hóa ()" không có bất kỳ thân phương thức nào. Vì điều này, bạn không thể làm như sau:

public class ImplementingClass extends AbstractClass
{
    // ERROR!
}

Không có phương pháp nào thực hiện abstractMethod()! Vì vậy, không có cách nào để JVM biết nó phải làm gì khi có được thứ gì đó như thế nào new ImplementingClass().abstractMethod().

Đây là một chính xác ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
}

Lưu ý rằng bạn không phải xác định implementedMethod()hoặc finalMethod(). Họ đã được xác định bởi AbstractClass.

Đây là một chính xác ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

Trong trường hợp này, bạn đã ghi đè implementedMethod().

Tuy nhiên, vì finaltừ khóa, sau đây là không thể.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
    public void finalMethod() { System.out.print("ERROR!"); }
}

Bạn không thể làm điều này bởi vì việc triển khai finalMethod()trong AbstractClassđược đánh dấu là triển khai cuối cùng của finalMethod(): không bao giờ thực hiện việc nào khác được cho phép.

Bây giờ bạn cũng có thể thực hiện một lớp trừu tượng hai lần:

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("second abstractMethod()"); }
}

Bây giờ ở đâu đó bạn có thể viết một phương pháp khác.

public tryItOut()
{
    ImplementingClass a = new ImplementingClass();
    AbstractClass b = new ImplementingClass();

    a.abstractMethod();    // prints "abstractMethod()"
    a.implementedMethod(); // prints "Overridden!"     <-- same
    a.finalMethod();       // prints "finalMethod()"

    b.abstractMethod();    // prints "abstractMethod()"
    b.implementedMethod(); // prints "Overridden!"     <-- same
    b.finalMethod();       // prints "finalMethod()"

    SecondImplementingClass c = new SecondImplementingClass();
    AbstractClass d = new SecondImplementingClass();

    c.abstractMethod();    // prints "second abstractMethod()"
    c.implementedMethod(); // prints "implementedMethod()"
    c.finalMethod();       // prints "finalMethod()"

    d.abstractMethod();    // prints "second abstractMethod()"
    d.implementedMethod(); // prints "implementedMethod()"
    d.finalMethod();       // prints "finalMethod()"
}

Lưu ý rằng mặc dù chúng tôi đã khai báo bmột AbstractClassloại, nó sẽ hiển thị "Overriden!". Điều này là do đối tượng chúng ta khởi tạo thực sự là một ImplementingClass, implementedMethod()tất nhiên là bị ghi đè. (Bạn có thể đã thấy điều này được gọi là đa hình.)

Nếu chúng ta muốn truy cập một thành viên cụ thể vào một lớp con cụ thể, trước tiên chúng ta phải bỏ xuống lớp con đó:

// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();

Cuối cùng, bạn không thể làm như sau:

public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
    ... // implementation
}

Mỗi lần chỉ có thể mở rộng một lớp. Nếu bạn cần mở rộng nhiều lớp, chúng phải là các giao diện. Bạn có thể làm được việc này:

public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
    ... // implementation
}

Đây là một giao diện ví dụ:

interface InterfaceA
{
    void interfaceMethod();
}

Điều này về cơ bản giống như:

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

Sự khác biệt duy nhất là cách thứ hai không cho trình biên dịch biết rằng đó thực sự là một giao diện. Điều này có thể hữu ích nếu bạn muốn mọi người chỉ thực hiện giao diện của bạn và không có ai khác. Tuy nhiên, như một quy tắc chung cho người mới bắt đầu, nếu lớp trừu tượng của bạn chỉ có các phương thức trừu tượng, có lẽ bạn nên biến nó thành một giao diện.

Sau đây là bất hợp pháp:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

Bạn không thể thực hiện các phương thức trong một giao diện. Điều này có nghĩa là nếu bạn triển khai hai giao diện khác nhau, các phương thức khác nhau trong các giao diện đó không thể va chạm. Vì tất cả các phương thức trong một giao diện là trừu tượng, bạn phải thực hiện phương thức và vì phương thức của bạn là triển khai duy nhất trong cây thừa kế, trình biên dịch biết rằng nó phải sử dụng phương thức của bạn.


5
@Imagist -1 cho mô tả sai cho câu lệnh c.im THỰCedMethod (); // in "execMethod ()", Nó sẽ in "Overriden!" luôn luôn
Sachin Kumar

2
@Sachin Tôi đã lãng phí nửa giờ để đánh máy để hiểu lý do tại sao nó sẽ in "execMethod ()" và sau đó tôi thấy bình luận của bạn. Có điều gì đó thay đổi với java hoặc những người khác chỉ bỏ qua lỗi lầm?
Rounak 22/03/2015

@SachinKumar Do thiếu phản hồi của tác giả, tôi đã tự mình khắc phục lỗi này. CMIIW.
Mateen Ulhaq

@SachinKumar Tôi hơi trễ trò chơi ở đây, nhưng bạn có nói rằng một sự tương tự tốt sẽ là khai báo phương thức (nhưng không thực hiện) trong tệp tiêu đề C ++ không?
Schwaitz

5
@SachinKumar tại sao lại c.implementedMethod()in "Overriden!"? SecondImplementingClasskhông ghi đè implementedMethod().
John Red

75

Một lớp Java trở nên trừu tượng theo các điều kiện sau:

1. Ít nhất một trong các phương thức được đánh dấu là trừu tượng:

public abstract void myMethod()

Trong trường hợp đó, trình biên dịch buộc bạn phải đánh dấu cả lớp là trừu tượng.

2. Lớp được đánh dấu là trừu tượng:

abstract class MyClass

Như đã nói: Nếu bạn có một phương thức trừu tượng, trình biên dịch buộc bạn phải đánh dấu cả lớp là trừu tượng. Nhưng ngay cả khi bạn không có bất kỳ phương thức trừu tượng nào, bạn vẫn có thể đánh dấu lớp là trừu tượng.

Sử dụng phổ biến:

Một cách sử dụng phổ biến của các lớp trừu tượng là cung cấp một phác thảo của một lớp tương tự như giao diện. Nhưng không giống như một giao diện, nó có thể cung cấp chức năng, tức là một số phần của lớp được triển khai và một số phần chỉ được phác thảo bằng một khai báo phương thức. ("trừu tượng")

Một lớp trừu tượng không thể được khởi tạo, nhưng bạn có thể tạo một lớp cụ thể dựa trên một lớp trừu tượng, sau đó có thể được khởi tạo. Để làm như vậy, bạn phải kế thừa từ lớp trừu tượng và ghi đè các phương thức trừu tượng, tức là thực hiện chúng.


1
Nitpick: 'điều kiện' thứ hai là dư thừa, vì bạn chỉ có thể khai báo một phương thức trừu tượng trong một lớp được khai báo rõ ràng là trừu tượng.
Stephen C

2
Đồng ý, lời khuyên không thực sự chính xác, hoặc được viết tốt, nó chỉ được định dạng độc đáo.
Trưa Silk

Nhưng lời khuyên của bạn 'để làm cho một lớp cụ thể' cũng bị hiểu sai. Bạn không tạo ra một lớp cụ thể, nó có hoặc không, tùy thuộc vào việc nó có trừu tượng hay không.
Trưa Silk

1
Đây chỉ là một lỗi bình thường. Một lớp trừu tượng không cần phải có bất kỳ phương thức trừu tượng nào. Bạn có thể tạo một lớp trừu tượng mà không có phương thức, hoặc chỉ với các phương thức cụ thể.
Jorn

1
10 năm muộn với trò chơi, nhưng đây là câu trả lời chính xác nhất. @Jorn bạn bối rối với câu trả lời tôi nghĩ. Tôi chắc chắn rằng nó được ngụ ý rằng abstracttừ khóa là tất cả những gì cần thiết cho một lớp là trừu tượng. Nhưng Một lớp cụ thể không thể chứa một abstract phương thức . Vì vậy, nếu lớp của bạn có một abstractphương thức, nó phải được khai báo là một abstractlớp cho trình biên dịch.
Rakib

24

Một lớp được khai báo sử dụng từ khóa trừu tượng được gọi là abstract class. Trừu tượng là một quá trình ẩn các chi tiết triển khai dữ liệu và chỉ hiển thị chức năng cho người dùng. Trừu tượng cho phép bạn tập trung vào những gì đối tượng làm thay vì cách nó thực hiện.

Những điều chính của lớp trừu tượng

  • Một lớp trừu tượng có thể có hoặc không chứa các phương thức trừu tượng. Có thể có các phương thức không trừu tượng.

    Một phương thức trừu tượng là một phương thức được khai báo mà không cần thực hiện (không có dấu ngoặc nhọn và theo sau là dấu chấm phẩy), như sau:

    Ví dụ : abstract void moveTo(double deltaX, double deltaY);

  • Nếu một lớp có ít nhất một phương thức trừu tượng thì lớp đó phải trừu tượng

  • Các lớp trừu tượng có thể không được khởi tạo (Bạn không được phép tạo đối tượng của lớp Trừu tượng)

  • Để sử dụng một lớp trừu tượng, bạn phải kế thừa nó từ một lớp khác. Cung cấp triển khai cho tất cả các phương thức trừu tượng trong đó.

  • Nếu bạn kế thừa một lớp trừu tượng, bạn phải cung cấp các triển khai cho tất cả các phương thức trừu tượng trong nó.

Khai báo lớp trừu tượng Chỉ định abstracttừ khóa trước lớp trong khi khai báo làm cho nó trừu tượng. Hãy xem mã dưới đây:

abstract class AbstractDemo{ }

Khai báo phương thức trừu tượng Chỉ định abstracttừ khóa trước phương thức trong khi khai báo làm cho nó trừu tượng. Hãy xem mã dưới đây,

abstract void moveTo();//no body

Tại sao chúng ta cần các lớp trừu tượng

Trong một ứng dụng vẽ hướng đối tượng, bạn có thể vẽ các vòng tròn, hình chữ nhật, đường thẳng, đường cong Bezier và nhiều đối tượng đồ họa khác. Các đối tượng này đều có một số trạng thái nhất định (ví dụ: vị trí, hướng, màu đường, màu tô) và các hành vi (đối với ex -: moveTo, xoay, thay đổi kích thước, vẽ) chung. Một số trạng thái và hành vi này giống nhau cho tất cả các đối tượng đồ họa (ví dụ: tô màu, vị trí và moveTo). Những người khác yêu cầu thực hiện khác nhau (ví dụ: thay đổi kích thước hoặc vẽ). Tất cả các đối tượng đồ họa phải có khả năng tự vẽ hoặc thay đổi kích thước, chúng chỉ khác nhau về cách chúng thực hiện.

Đây là một tình huống hoàn hảo cho một siêu lớp trừu tượng. Bạn có thể tận dụng sự tương đồng và khai báo tất cả các đối tượng đồ họa để kế thừa từ cùng một đối tượng cha trừu tượng (ví dụ GraphicObject:) như trong hình dưới đây. nhập mô tả hình ảnh ở đây

Đầu tiên, bạn khai báo một lớp trừu tượng GraphicObject, để cung cấp các biến và phương thức thành viên được chia sẻ hoàn toàn bởi tất cả các lớp con, chẳng hạn như vị trí hiện tại và phương thức moveTo. GraphicObjectcũng đã khai báo các phương thức trừu tượng, chẳng hạn như vẽ hoặc thay đổi kích thước, cần phải được thực hiện bởi tất cả các lớp con nhưng phải được thực hiện theo các cách khác nhau. Các GraphicObjectlớp có thể trông giống như thế này:

abstract class GraphicObject {

  void moveTo(int x, int y) {
    // Inside this method we have to change the position of the graphic 
    // object according to x,y     
    // This is the same in every GraphicObject. Then we can implement here. 
  }

  abstract void draw(); // But every GraphicObject drawing case is 
                        // unique, not common. Then we have to create that 
                        // case inside each class. Then create these    
                        // methods as abstract 
  abstract void resize();
}

Việc sử dụng phương thức trừu tượng trong các lớp con Mỗi lớp con không trừu tượng của GraphicObject, chẳng hạn như CircleRectangle, phải cung cấp các triển khai cho các phương thức drawresize.

class Circle extends GraphicObject {
  void draw() {
    //Add to some implementation here
  }
  void resize() {
    //Add to some implementation here   
  }
}
class Rectangle extends GraphicObject {
  void draw() {
    //Add to some implementation here
  }
  void resize() {
    //Add to some implementation here
  }
}

Bên trong mainphương thức bạn có thể gọi tất cả các phương thức như thế này:

public static void main(String args[]){
   GraphicObject c = new Circle();
   c.draw();
   c.resize();
   c.moveTo(4,5);   
}

Các cách để đạt được sự trừu tượng hóa trong Java

Có hai cách để đạt được sự trừu tượng trong java

  • Lớp trừu tượng (0 đến 100%)
  • Giao diện (100%)

Lớp trừu tượng với các hàm tạo, thành viên dữ liệu, phương thức, v.v.

abstract class GraphicObject {

  GraphicObject (){
    System.out.println("GraphicObject  is created");
  }
  void moveTo(int y, int x) {
       System.out.println("Change position according to "+ x+ " and " + y);
  }
  abstract void draw();
}

class Circle extends GraphicObject {
  void draw() {
    System.out.println("Draw the Circle");
  }
}

class TestAbstract {  
 public static void main(String args[]){

   GraphicObject  grObj = new Circle ();
   grObj.draw();
   grObj.moveTo(4,6);
 }
}

Đầu ra:

GraphicObject  is created
Draw the Circle
Change position according to 6 and 4

Ghi nhớ hai quy tắc:

  • Nếu lớp có một vài phương thức trừu tượng và một vài phương thức cụ thể, hãy khai báo nó như là một abstractlớp.

  • Nếu lớp chỉ có các phương thức trừu tượng, hãy khai báo nó là một interface.

Người giới thiệu:


Tại sao thứ tự của các tham số x và y trong moveTo khác nhau trong ví dụ trên, ví dụ bên dưới và đầu ra từ ví dụ bên dưới? Nếu chúng ta đang cố gắng minh họa tầm quan trọng của các khái niệm như giao diện và các lớp trừu tượng, chúng ta có nên sử dụng các chữ ký hàm giống như các giao diện hoặc các lớp trừu tượng mà chúng ta đang triển khai hoặc mở rộng một cách nhất quán không?
Jonathan Rys

hai quy tắc cho đi
LiNKeR

4

Đó là một lớp không thể khởi tạo và buộc các lớp thực hiện, có thể, thực hiện các phương thức trừu tượng mà nó vạch ra.


3

Nói một cách đơn giản, bạn có thể nghĩ về một lớp trừu tượng giống như một Giao diện với nhiều khả năng hơn một chút.

Bạn không thể khởi tạo một Giao diện, cũng dành cho một lớp trừu tượng.

Trên giao diện của bạn, bạn chỉ có thể xác định các tiêu đề phương thức và TẤT CẢ các trình triển khai buộc phải thực hiện tất cả chúng. Trên một lớp trừu tượng, bạn cũng có thể định nghĩa các tiêu đề phương thức của mình nhưng ở đây - với sự khác biệt của giao diện - bạn cũng có thể định nghĩa phần thân (thường là cài đặt mặc định) của phương thức. Ngoài ra, khi các lớp khác mở rộng (lưu ý, không triển khai và do đó bạn cũng có thể chỉ có một lớp trừu tượng cho mỗi lớp con), lớp trừu tượng của chúng, chúng không bị buộc phải thực hiện tất cả các phương thức của lớp trừu tượng của bạn, trừ khi bạn đã chỉ định một phương thức trừu tượng ( trong trường hợp như vậy nó hoạt động như đối với các giao diện, bạn không thể định nghĩa thân phương thức).

public abstract class MyAbstractClass{
  public abstract void DoSomething();
}

Mặt khác, đối với các phương thức bình thường của một lớp trừu tượng, "người thừa kế" có thể chỉ sử dụng hành vi mặc định hoặc ghi đè lên nó, như bình thường.

Thí dụ:

public abstract class MyAbstractClass{

  public int CalculateCost(int amount){
     //do some default calculations
     //this can be overriden by subclasses if needed
  }

  //this MUST be implemented by subclasses
  public abstract void DoSomething();
}

Câu trả lời này không hữu ích nếu OP không biết giao diện là gì. Vì các lớp và giao diện trừu tượng có liên quan với nhau, rất khó có khả năng OP sẽ biết cái này mà không biết cái kia.
Tưởng tượng

Nhưng nó có thể. Có thể là anh ta chỉ biết giao diện là gì và cách thức hoạt động, và sau đó anh ta bắt gặp các lớp trừu tượng và tự hỏi tại sao người ta cần chúng. Không thể như vậy sao?
Juri

3

Từ tài liệu orory

Các phương pháp và lớp học trừu tượng:

Một lớp trừu tượng là một lớp được khai báo trừu tượng, nó có thể bao gồm hoặc không bao gồm các phương thức trừu tượng

Các lớp trừu tượng không thể được khởi tạo, nhưng chúng có thể được phân lớp

Một phương thức trừu tượng là một phương thức được khai báo mà không cần thực hiện (không có dấu ngoặc nhọn và theo sau là dấu chấm phẩy), như sau:

abstract void moveTo(double deltaX, double deltaY);

Nếu một lớp bao gồm các phương thức trừu tượng, thì chính lớp đó phải được khai báo là trừu tượng, như trong:

public abstract class GraphicObject {
   // declare fields
   // declare nonabstract methods
   abstract void draw();
}

Khi một lớp trừu tượng được phân lớp, lớp con thường cung cấp các triển khai cho tất cả các phương thức trừu tượng trong lớp cha của nó. Tuy nhiên, nếu không, thì lớp con cũng phải được khai báo là trừu tượng .

abstract classesinterfacescó liên quan, hãy xem các câu hỏi SE bên dưới:

Sự khác biệt giữa một giao diện và lớp trừu tượng là gì?

Làm thế nào tôi có thể giải thích sự khác biệt giữa một lớp Giao diện và lớp Trừu tượng?


3

Nhận câu trả lời của bạn ở đây:

Lớp trừu tượng vs Giao diện trong Java

Một lớp trừu tượng có thể có một phương thức cuối cùng?

BTW - đó là những câu hỏi bạn đã hỏi gần đây. Hãy suy nghĩ về một câu hỏi mới để xây dựng danh tiếng ...

Biên tập:

Chỉ cần nhận ra rằng các áp phích của câu hỏi này và các câu hỏi được tham chiếu có cùng tên hoặc ít nhất là tên tương tự nhưng id người dùng luôn khác nhau. Vì vậy, có một vấn đề kỹ thuật, keyur đó có vấn đề khi đăng nhập lại và tìm câu trả lời cho câu hỏi của anh ta hoặc đây là một loại trò chơi để giải trí cho cộng đồng SO;)


Và đó là lý do tại sao tôi đã kiểm tra 'wiki cộng đồng' - người ta không nên tăng danh tiếng thông qua việc phản ứng với những câu hỏi đó;)
Andreas Dolk

1

Ít bổ sung cho tất cả các bài viết.

Đôi khi bạn có thể muốn khai báo một lớp và chưa biết cách định nghĩa tất cả các phương thức thuộc về lớp đó. Ví dụ, bạn có thể muốn khai báo một lớp có tên là Writer và bao gồm trong đó một phương thức thành viên có tên là write () . Tuy nhiên, bạn không biết cách viết() vì nó khác nhau đối với từng loại thiết bị Writer. Tất nhiên, bạn có kế hoạch xử lý việc này bằng cách lấy lớp con của Nhà văn, chẳng hạn như Máy in, Đĩa, Mạng và Bảng điều khiển.


1

Một lớp trừu tượng không thể được khởi tạo trực tiếp, nhưng phải bắt nguồn từ để có thể sử dụng được. Một lớp PHẢI trừu tượng nếu nó chứa các phương thức trừu tượng: trực tiếp

abstract class Foo {
    abstract void someMethod();
}

hoặc gián tiếp

interface IFoo {
    void someMethod();
}

abstract class Foo2 implements IFoo {
}

Tuy nhiên, một lớp có thể trừu tượng mà không chứa các phương thức trừu tượng. Đó là một cách để ngăn chặn việc khởi tạo trực tiếp, vd

abstract class Foo3 {
}

class Bar extends Foo3 {

}

Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!

Kiểu thứ hai của các lớp trừu tượng có thể được sử dụng để tạo các lớp "giống như giao diện". Không giống như các giao diện, một lớp trừu tượng được phép chứa các phương thức và các biến đối tượng không trừu tượng. Bạn có thể sử dụng điều này để cung cấp một số chức năng cơ bản để mở rộng các lớp.

Một mô hình thường gặp khác là triển khai chức năng chính trong lớp trừu tượng và xác định một phần của thuật toán trong một phương thức trừu tượng được thực hiện bởi một lớp mở rộng. Ví dụ ngu ngốc:

abstract class Processor {
    protected abstract int[] filterInput(int[] unfiltered);

    public int process(int[] values) {
        int[] filtered = filterInput(values);
        // do something with filtered input
    }
}

class EvenValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove odd numbers
    }
}

class OddValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove even numbers
    }
}

1

Giải pháp - lớp cơ sở (trừu tượng)

public abstract class Place {

String Name;
String Postcode;
String County;
String Area;

Place () {

        }

public static Place make(String Incoming) {
        if (Incoming.length() < 61) return (null);

        String Name = (Incoming.substring(4,26)).trim();
        String County = (Incoming.substring(27,48)).trim();
        String Postcode = (Incoming.substring(48,61)).trim();
        String Area = (Incoming.substring(61)).trim();

        Place created;
        if (Name.equalsIgnoreCase(Area)) {
                created = new Area(Area,County,Postcode);
        } else {
                created = new District(Name,County,Postcode,Area);
        }
        return (created);
        }

public String getName() {
        return (Name);
        }

public String getPostcode() {
        return (Postcode);
        }

public String getCounty() {
        return (County);
        }

public abstract String getArea();

}

1
hãy thử định dạng tất cả mã dưới dạng mã và vui lòng thêm một số giải thích, ngay bây giờ điều này khó có thể được coi là một câu trả lời.
NomeN

3
cho đến khi và trừ khi bạn không đưa ra lời giải thích về mã của mình. Bạn sẽ được coi là một người trả lời xấu. Vì vậy, vui lòng đưa ra lời giải thích ở đây
devsda

0

Một lớp trừu tượng là một lớp được khai báo là trừu tượng - nó có thể bao gồm hoặc không bao gồm các phương thức trừu tượng. Các lớp trừu tượng không thể được khởi tạo, nhưng chúng có thể được phân lớp.

Nói cách khác, một lớp được khai báo với từ khóa trừu tượng, được gọi là lớp trừu tượng trong java. Nó có thể có trừu tượng (phương thức không có cơ thể) và phương pháp không trừu tượng (phương pháp với cơ thể).

Lưu ý quan trọng: - Các lớp trừu tượng không thể được sử dụng để khởi tạo các đối tượng, chúng có thể được sử dụng để tạo các tham chiếu đối tượng, bởi vì cách tiếp cận đa hình thời gian chạy của Java được thực hiện thông qua việc sử dụng các tham chiếu siêu lớp. Vì vậy, nó phải có khả năng tạo một tham chiếu đến một lớp trừu tượng để nó có thể được sử dụng để trỏ đến một đối tượng lớp con. Bạn sẽ thấy tính năng này trong ví dụ dưới đây

abstract class Bike{  
  abstract void run();  
}  

class Honda4 extends Bike{  
    void run(){
        System.out.println("running safely..");
    }  

    public static void main(String args[]){  
       Bike obj = new Honda4();  
       obj.run();  
    }  
} 

0

Một lớp trừu tượng là một lớp không được triển khai đầy đủ nhưng cung cấp một cái gì đó của kế hoạch chi tiết cho các lớp con. Nó có thể được thực hiện một phần ở chỗ nó chứa các phương thức cụ thể được xác định đầy đủ, nhưng nó cũng có thể chứa các phương thức trừu tượng. Đây là các phương thức có chữ ký nhưng không có phương thức. Bất kỳ lớp con nào cũng phải định nghĩa một phần thân cho mỗi phương thức trừu tượng, nếu không nó cũng phải được khai báo là trừu tượng. Bởi vì các lớp trừu tượng không thể được khởi tạo, chúng phải được mở rộng thêm ít nhất một lớp con để được sử dụng. Hãy nghĩ về lớp trừu tượng là lớp chung và các lớp con ở đó để điền thông tin còn thiếu.


0

Lớp có thể có cả phương pháp cụ thể và không cụ thể tức là có và không có thân.

  1. Các phương thức không thực hiện phải chứa từ khóa 'trừu tượng'.
  2. Lớp trừu tượng không thể được khởi tạo.

-1

Nó không làm gì cả, chỉ cung cấp một mẫu chung sẽ được chia sẻ cho lớp con của nó

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.