2015-09-05 19 views
5

Không có cách nào để tạo đối tượng sử dụng lớp trừu tượng. Nhưng khi sử dụng lớp bên trong vô danh, bạn có thể chạy đoạn mã sau. Và không chỉ có phương pháp start() không thể truy cập được, do đó lý do để chạy chương trình sau đây mà không đưa ra bất kỳ lỗi biên dịch nào và cơ chế truy cập phương thức start() là gì.Có thể khởi tạo lớp trừu tượng bằng cách sử dụng lớp bên trong vô danh và cơ chế để truy cập phương thức trong đó

abstract class Vehicle{ 
     abstract void park(); 
    } 

    class Demo{ 
     public static void main(String args[]){ 
      Vehicle v1=new Vehicle(){ 
       int speed; 
       void park(){ 
        System.out.println("Parking for cars..."); 
       } 
       void start(){ 
        System.out.println("Start..."); 
       } 
      }; 
      v1.park(); 
     } 
    } 

Trả lời

6

Hãy xem xét đoạn mã sau (mã 2).

abstract class Vehicle{ 
    abstract void park(); 
} 

class Demo{ 
    static class Car extends Vehicle { 
     int speed; 
     void park(){ 
       System.out.println("Parking for cars..."); 
     } 
    } 

    public static void main(String args[]){ 
     Vehicle v1=new Car(); 
     v1.park(); 
    } 
} 

Không có gì ngạc nhiên khi đoạn mã trước đó không có lỗi trình biên dịch.
Xe mở rộng Xe và Xe không phải là trừu tượng. Do đó bạn có thể khởi tạo nó.

Cho phép xem những gì sẽ xảy ra khi 2 mã được biên dịch:

javac *.java 
list .class files 
Demo$Car.class Demo.class Vehicle.class 

Và đây là những gì sẽ xảy ra khi các mã trong câu hỏi (mã 1) được biên soạn:

javac *.java 
list .class files 
Demo$1.class Demo.class Vehicle.class 

Chúng tôi nhận được cùng một ngoại trừ chúng ta có được Demo $ 1.class trong mã 1 và Demo $ Car.class trong mã 2.
Điều đó xảy ra vì mã 1 thực sự đang tạo một lớp kế thừa từ Xe. Một cái gọi là lớp vô danh. Lớp học không có tên (*) nhưng nó vẫn là một lớp học chính thức được thừa hưởng từ Xe và có thể được khởi tạo ngay khi Xe có thể được khởi tạo.

Mã này:

Vehicle v1=new Vehicle(){ 

KHÔNG instantiating một đối tượng của lớp Vehicle. Nó là instantiating một đối tượng của một lớp mà kế thừa từ xe mà không có tên.

(*) Thực ra nó có tên. Tên của nó là "1 in Demo" hay còn gọi là Demo $ 1. JVM cần một tên để có thể chạy nó, bạn không thể chỉ cần nói cho JVM chạy một cái gì đó mà không nói cho nó những gì để chạy. Tên là tên không phải là tên hợp lệ của một lớp; không thể đặt tên một lớp là 1. Đây là do dessign vì nó đảm bảo rằng các tên lớp đồng nghĩa sẽ không đụng độ với các tên lớp bình thường.

+0

Bạn có thể muốn bao gồm các lệnh Terminal của bạn chỉ dành cho hệ thống * nix. –

+0

Ok, sẽ làm rõ điều đó. javac là phổ biến đối với bất kỳ nền tảng nào với JDK. –

4

đây chính xác là ý tưởng trong lớp trừu tượng. bạn không thể instanciate lớp trừu tượng, nhưng bạn có thể instanciate bất kỳ tiểu lớp của nó mà thực hiện các phương pháp trừu tượng. Các lớp con như vậy có thể là các lớp cụ thể hoặc các lớp ẩn danh như bạn đã làm ở đây, vì vậy không có lý do nào cho mã này không biên dịch

1

Anonymous class có nghĩa là bạn đã khai báo địa phương class trong Demo. Lớp ẩn danh là biểu thức có thể có triển khai phương pháp trừu tượng. Chủ yếu là lớp ẩn danh là việc triển khai cục bộ của interface hoặc abstractclass phải chứa các phương thức trừu tượng và thực hiện theo cách thức trừu tượng các phương thức trừu tượng của lớp trừu tượng. Vì vậy, trong ngắn hạn, bạn có thể nhanh chóng lớp abstract với lớp ẩn danh.

Ở đây, bạn thực sự tuyên bố toàn bộ lớp học Vehicle là lớp ẩn danh trong Demo của bạn với yêu cầu triển khai. Lưu ý rằng bạn sẽ có tệp Demo$1.class sau khi biên soạn lớp Demo là lớp ẩn danh và triển khai Vehicle trong Demo của bạn.

1

Mặc dù bạn đang viết Phương tiện mới() nhưng nó không tạo ra một thể hiện của lớp Xe. Việc tạo một thể hiện của loại phụ của Xe không có bất kỳ tên nào

1

Không có cách nào để tạo đối tượng sử dụng lớp trừu tượng. Nhưng khi sử dụng lớp bên trong vô danh, bạn có thể chạy đoạn mã sau. Lý do cho runinng là gì sau chương trình mà không đưa ra bất kỳ lỗi biên dịch nào.

Mã chạy vì bạn đang không phải tạo đối tượng trực tiếp từ abstract class. Khi bạn tạo một lớp học vô danh từ abstract class hoặc interface bạn thực sự đang tạo một lớp mới mở rộng/triển khai đến abstract class hoặc interface.

Nó không thực sự quan trọng cho dù bạn đang sử dụng một lớp bên trong hay không.


Tóm lại, khi bạn tạo một lớp ẩn danh, đây là lớp "không tên" mở rộng lớp trừu tượng được khởi tạo!

Các vấn đề liên quan