1. 程式人生 > >iOS應用內支付(內購)

iOS應用內支付(內購)

本文會給大家詳細介紹iOS內購,這是本人16年5月底的開發過程,希望對看完此篇文章的人有所幫助。 
本文基於XcodeVersion 7.3 (7D175)版本,手機是iPhone 6,9.3系統。 
部分地方直接摘自網路,基本上是我的邏輯,省時省心省力。

一. 建立測試App

首先你需要登入 App的ItunesConnection,你會看到如下介面 
這裡寫圖片描述

簡單的介紹一下這幾個選項 
1.我的App主要用於管理自己的App應用,例如編輯資料,上架,下架等。 
2.銷售和趨勢主要是來檢視App在各個平臺的下載量,收入等方面資料,裡面有曲線圖等圖文結合的方式給我們參考。 
3.付款和財務報告顯示的是你的收入以及付款等相關資訊。 
4.iAd主要是跟廣告有關,開發者可以登入到Workbench,通過iAd對應用的廣告進行控制。 
5.使用者和職能用於生成相應賬號,例如蘋果沙河

測試賬號。 
6.協議,稅務和銀行業務則是你銀行相關賬戶的資訊設定。 
在這裡我們選擇第一個選項,我的App, 然後點選左上角的加號,新建一個用來測試用的App。 
這裡寫圖片描述

點新建 App,會出現新建視窗; 
這裡寫圖片描述

在這裡有幾個需要填寫的地方,名稱自己取,平臺IOS,語言選擇了簡體中文,套裝ID也就是你的Bundle Identifier,需要你在Certificates頁面 申請BundleID,SKU可以理解為使用者看一看到的唯一標示,會體現在你的app的App Store的連結中。

二.新增內購

App建立好之後,我們開啟建立的App,在左上角選擇功能,會看到左側的App 內購買專案。我們點選右下角的加號,為App新增內購專案。 
這裡寫圖片描述

之後我們會看到型別的選項,如下圖

這裡寫圖片描述

官方的註釋寫的很清楚了,只在這裡簡單的說下前兩種: 
- 消耗型專案 就像你玩遊戲需要買金幣,買鑽石等,只要花錢就可以無限次的購買 
- 非消耗型專案 就像你在App Store購買App,買了一次之後就不用再買第二次,你擁有永久使用權。 
在我們的app中,是充值會員,所以選擇的是第一種,可以無限次購買。

這裡寫圖片描述

這裡有幾個選項,需要填寫商品名稱,產品ID以及價格等級,簡單說明一下 
1. 商品名稱根據你的消費道具的實際意義來說明,比如“100顆寶石”,“100金幣”等。 
2. 產品ID是比較重要的,由專案自定義,只要唯一即可,因為測試,我在這裡隨便填寫的123,在實際應用中,一定要認真填寫。 
3. 價格等級的話“檢視價格表”中有對應的說明,可以對照著表中每個國家的貨幣價格與等級來選擇 
接下來是語言選擇,和上傳快照如下圖

這裡寫圖片描述

點選新增語言,填寫名稱和描述,這裡我們依然選擇簡體中文,如下

這裡寫圖片描述

稽核備註,根據實際情況填寫,可以不填。而下面的螢幕快照,則是商品圖片,以畫素為單位,最低尺寸為321,390,尺寸需求如下圖,上傳即可。

這裡寫圖片描述

到這裡為止, 我們的內購專案則新增完成。接下來則是測試階段了。

三.申請沙盒測試賬號(用來測試購買專案)

這個賬號,是利用蘋果的沙盒測試環境來模擬AppStore的購買流程,你肯定不會想要用真實RMB去購買測試吧? 
首先我們回到iTunes Connect中,在這裡我們選擇使用者和職能。

這裡寫圖片描述

然後在上面的第三個選項沙箱技術測試員中點選加號,新增測試員。

這裡寫圖片描述

在資訊填寫頁面只簡單說兩句。 
所有資訊都可以隨意填寫,不用管是否真實。 
App Store地區選擇,一定要選對,它對應的是你建立的App的地區, 你App是中國的話, 在這裡我們依然選擇中國。 
此賬號只能用來測試,不要在正式的appstore上使用 
填寫完畢,點選儲存後,我們則生成一個測試賬號,當然這個賬號是可以隨時刪除和新增的。

這裡寫圖片描述

之後終於到了寫程式碼的時候了,點開你的Xcode建立你的專案! 
大部分程式碼都可以在.m檔案中實現。

#import "ViewController.h"
#import <StoreKit/StoreKit.h>
#import "SVProgressHUD.h"

@interface ViewController ()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
@property (nonatomic,copy) NSString *currentProId;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(100, 100, 100, 100);
    button.backgroundColor = [UIColor greenColor];
    [button setTitle:@"6元" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
    [self.view addSubview:button];
}


- (void)btnClick:(UIButton *)button
{
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    _currentProId = @"123";
    if([SKPaymentQueue canMakePayments]){
        [self requestProductData:product];
    }else{
        NSLog(@"不允許程式內付費");
    }
}

//去蘋果伺服器請求商品
- (void)requestProductData:(NSString *)type{
    NSLog(@"-------------請求對應的產品資訊----------------");

    [SVProgressHUD showWithStatus:nil maskType:SVProgressHUDMaskTypeBlack];

    NSArray *product = [[NSArray alloc] initWithObjects:type,nil];

    NSSet *nsset = [NSSet setWithArray:product];
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
    request.delegate = self;
    [request start];

}

//收到產品返回資訊
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{

    NSLog(@"--------------收到產品反饋訊息---------------------");
    NSArray *product = response.products;
    if([product count] == 0){
        [SVProgressHUD dismiss];
        NSLog(@"--------------沒有商品------------------");
        return;
    }

    NSLog(@"productID:%@", response.invalidProductIdentifiers);
    NSLog(@"產品付費數量:%lu",(unsigned long)[product count]);

    SKProduct *p = nil;
    for (SKProduct *pro in product) {
        NSLog(@"%@", [pro description]);
        NSLog(@"%@", [pro localizedTitle]);
        NSLog(@"%@", [pro localizedDescription]);
        NSLog(@"%@", [pro price]);
        NSLog(@"%@", [pro productIdentifier]);

        if([pro.productIdentifier isEqualToString:_currentProId]){
            p = pro;
        }
    }

    SKPayment *payment = [SKPayment paymentWithProduct:p];

    NSLog(@"傳送購買請求");
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

//請求失敗
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
    [SVProgressHUD showErrorWithStatus:@"支付失敗"];
    NSLog(@"------------------錯誤-----------------:%@", error);
}

- (void)requestDidFinish:(SKRequest *)request{
    [SVProgressHUD dismiss];
    NSLog(@"------------反饋資訊結束-----------------");
}
//沙盒測試環境驗證
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式環境驗證
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"
/**
 *  驗證購買,避免越獄軟體模擬蘋果請求達到非法購買問題
 *
 */
-(void)verifyPurchaseWithPaymentTransaction{
    //從沙盒中獲取交易憑證並且拼接成請求體資料
    NSURL *receiptUrl=[[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receiptData=[NSData dataWithContentsOfURL:receiptUrl];

    NSString *receiptString=[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];//轉化為base64字串

    NSString *bodyString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptString];//拼接請求資料
    NSData *bodyData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];


    //建立請求到蘋果官方進行購買驗證
    NSURL *url=[NSURL URLWithString:SANDBOX];
    NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url];
    requestM.HTTPBody=bodyData;
    requestM.HTTPMethod[email protected]"POST";
    //建立連線併發送同步請求
    NSError *error=nil;
    NSData *responseData=[NSURLConnection sendSynchronousRequest:requestM returningResponse:nil error:&error];
    if (error) {
        NSLog(@"驗證購買過程中發生錯誤,錯誤資訊:%@",error.localizedDescription);
        return;
    }
    NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"%@",dic);
    if([dic[@"status"] intValue]==0){
        NSLog(@"購買成功!");
        NSDictionary *dicReceipt= dic[@"receipt"];
        NSDictionary *dicInApp=[dicReceipt[@"in_app"] firstObject];
        NSString *productIdentifier= dicInApp[@"product_id"];//讀取產品標識
        //如果是消耗品則記錄購買數量,非消耗品則記錄是否購買過
        NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
        if ([productIdentifier isEqualToString:@"123"]) {
            int purchasedCount=[defaults integerForKey:productIdentifier];//已購買數量
            [[NSUserDefaults standardUserDefaults] setInteger:(purchasedCount+1) forKey:productIdentifier];
        }else{
            [defaults setBool:YES forKey:productIdentifier];
        }
        //在此處對購買記錄進行儲存,可以儲存到開發商的伺服器端
    }else{
        NSLog(@"購買失敗,未通過驗證!");
    }
}
//監聽購買結果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{
    for(SKPaymentTransaction *tran in transaction){
        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchased:{
                NSLog(@"交易完成");
                // 傳送到蘋果伺服器驗證憑證
                [self verifyPurchaseWithPaymentTransaction];
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];

            }
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"商品新增進列表");

                break;
            case SKPaymentTransactionStateRestored:{
                NSLog(@"已經購買過商品");

                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
            }
                break;
            case SKPaymentTransactionStateFailed:{
                NSLog(@"交易失敗");
                [[SKPaymentQueue defaultQueue] finishTransaction:tran];
                [SVProgressHUD showErrorWithStatus:@"購買失敗"];
            }
                break;
            default:
                break;
        }
    }
}

//交易結束
- (void)completeTransaction:(SKPaymentTransaction *)transaction{
    NSLog(@"交易結束");

    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}


- (void)dealloc{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195

在這裡需要注意幾點, 
1. 程式碼中的_currentProId所填寫的是你的購買專案的的ID,這個和第二步建立的內購的productID要一致;本例中是 123。 
2. 在監聽購買結果後,一定要呼叫[[SKPaymentQueue defaultQueue] finishTransaction:tran];來允許你從支付佇列中移除交易。 
3. 沙盒環境測試appStore內購流程的時候,請使用沒越獄的裝置。 
4. 請務必使用真機來測試,一切以真機為準。 
5. 專案的Bundle identifier需要與您申請AppID時填寫的bundleID一致,不然會無法請求到商品資訊。 
6. 真機測試的時候,一定要退出原來的賬號,才能用沙盒測試賬號 
7. 二次驗證,請注意區分巨集, 測試用沙盒驗證,App Store稽核的時候也使用的是沙盒購買,所以驗證購買憑證的時候需要判斷返回Status Code決定是否去沙盒進行二次驗證,為了線上使用者的使用,驗證的順序肯定是先驗證正式環境,此時若返回值為21007,就需要去沙盒二次驗證,因為此購買的是在沙盒進行的。

附:蘋果支付錯誤目錄

Status Code Description
21000 The App Store could not read the JSON object you provided.
21002 The data in the receipt-data property was malformed or missing.
21003 The receipt could not be authenticated.
21004 The shared secret you provided does not match the shared secret on file for your account.Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
21005 The receipt server is not currently available.
21006 This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
21007 This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
21008 This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.

相關推薦

iOS應用支付

本文會給大家詳細介紹iOS內購,這是本人16年5月底的開發過程,希望對看完此篇文章的人有所幫助。  本文基於XcodeVersion 7.3 (7D175)版本,手機是iPhone 6,9.3系統。  部分地方直接摘自網路,基本上是我的邏輯,省時省心省力。 一. 建立測

iOS應用支付IAP服務端端校驗詳解

imageview sof 客戶端 標識 知識庫 ndb json replace undle IAP流程 IAP流程分為兩種: 一種是直接使用Apple的服務器進行購買和驗證, 另一種就是自己假設服務器進行驗證。由於國內網絡連接Apple服務器驗證非常慢,而且也為了防止黑

iOS應用支付IAP詳解

在iOS開發中如果涉及到虛擬物品的購買,就需要使用IAP服務,我們今天來看看如何實現。 在實現程式碼之前我們先做一些準備工作,一步步來看。 1、IAP流程 IAP流程分為兩種,一種是直接使用Apple的伺服器進行購買和驗證,另一種就是自己假設伺服

ios 應用支付In-App Purchase,沙盒測試,後臺驗證

1.蘋果iTunes Connect內購產品資訊錄入。 1)建立app內購買專案(Create New),選擇型別: 1.消耗型專案 對於消耗型 App 內購買專案,使用者每次下載時都必須進行購買。一次性服務通常屬於消耗型專案,例如釣魚App 中的魚餌。 2.非消耗型

ios 應用支付In-App Purchase,沙盒測試,後臺驗證

1.蘋果iTunes Connect內購產品資訊錄入。 1)建立app內購買專案(Create New),選擇型別: 1.消耗型專案 對於消耗型 App 內購買專案,使用者每次下載時都必須進行購買。一次性服務通常屬於消耗型專案,例如釣魚App 中的魚餌。 2.非消耗型專案

Java學習筆記05--強制型別轉換 ;部類瞭解即可 ;Java異常體系及異常處理;iOS中的try catch 塊

===============java相關講解============= 強制型別轉換: 基本資料型別的轉換 小資料型別---->大的資料型別 自動型別轉換 大資料型別----->小資料型別 強制型別轉換

IOS 應用跳轉 IOS9白名單

tom super created reat 獲取 import 字符 ges ict 跳轉到指定app的實現 IOS中應用的跳轉是通過URL實現的,因此在實現應用跳轉之前我們要設置一下對應的URL。 圖一(尋找配置軟件的URL) 圖二(具體配置選項) 註意: 如果IO

Cache與Buffer簡化理解

linux 內存技術 Cache(緩存)是“讀”磁盤時針對內存的一種優化技術。系統進程第一次將從硬盤讀取過來的數據緩存到內存中,當第二次讀取時直接從內存中直接讀取,可提高數據讀取速率。Buffer(緩沖)是“寫”磁盤時針對內存的一種優化技術。系統進程想要將數據寫入磁盤,經過內存時,內存會將數據分散實時

java 部類inner class詳解

ron isp https nerd 對象 重寫 prot print 元素 優點 ⒈ 內部類對象可以訪問創建它的對象的實現,包括私有數據; ⒉ 內部類不為同一包的其他類所見,具有很好的封裝性; ⒊ 使用內部類可以很方便的編寫事件驅動程序; ⒋ 匿名內部類可以方便的定義運行

BZOJ3243 NOI2013向量隨機化

max style fine stdin 奇技淫巧 ont 前綴 int efi   考慮奇技淫巧。   首先是k=2。對向量維護一個前綴和,每次將當前向量與前綴和點乘。如果點乘結果不等於i-1&1,說明當前向量至少和之前的某個向量的數量積是2的倍數,暴力找就可以了

連線INNER JOIN

內連線組合兩張表,並且基於兩張表中的關聯關係來連線它們。使用內連線需要指定表中哪些欄位組成關聯關係,並且需要指定基於什麼條件進行連線。內連線的語法如下: INNER JOIN table_name ON condition 其中table_name 為被關聯的表名,condition則為進行連線時

有兩個關於部類Inner Class的示例

  有兩個關於內部類(Inner Class)的示例  第一個,演示一個簡單的外部類使用內部類示例: public class OuterClass {     //內部類    &n

iOS 應用上架流程提交到AppStore

1、賬號準備 1.1  登入蘋果開發者中心   https://developer.apple.com/ 1.2  輸入Apple ID和密碼(沒有則需註冊) 1.3  加入蘋果開發者計劃(如已加入,可跳過這一步)

iOS應用架構談3:網路層設計方案

前言 網路層在一個App中也是一個不可缺少的部分,工程師們在網路層能夠發揮的空間也比較大。另外,蘋果對網路請求部分已經做了很好的封裝,業界的AFNetworking也被廣泛使用。其它的ASIHttpRequest,MKNetworkKit啥的其實也都還不錯,但前者已經棄坑,後者

靜態巢狀類(Static Nested Class)和部類Inner Class的不同

答:Static Nested Class是被宣告為靜態(static)的內部類,它可以不依賴於外部類例項被例項化。而通常的內部類需要在外部類例項化後才能例項化,其語法看起來挺詭異的,如下所示。 /**  * 撲克類(一副撲克)  * @author 駱昊  *  */pu

向量點乘和外積叉乘概念及幾何意義

向量的內積(點乘) 定義 概括地說,向量的內積(點乘/數量積)。對兩個向量執行點乘運算,就是對這兩個向量對應位一一相乘之後求和的操作,如下所示,對於向量a和向量b:   a和b的點積公式為: 這裡要求一維向量a和向量b的行列數相同。注意:點乘的結果是一個標量(數量

部類多繼承

首先,要清楚繼承的目的是為了複用。Java只能繼承一個類,不支援多繼承。即沒有extends Class1,Class2的語句形式。但我們可以通過內部類現模擬這一實現。 java的非靜態內部類可以使用外部類的所有成員方法和變數。這給繼承多個類的同名成員並共享帶來可能。同

靜態巢狀類Static Nested Class部類Inner Class

一. 什麼是巢狀類及內部類? 可以在一個類的內部定義另一個類, 這種類稱為巢狀類(nested classes),它有兩種型別: 靜態巢狀類和非靜態巢狀類.靜態巢狀類使用很少, 最重要的是非靜態巢狀類, 也即是被稱作為 內部類(inner).巢狀類從JDK1.1

靜態巢狀類(Static Nested Class)和部類Inner Class的不同?

Static Nested Class是被宣告為靜態(static)的內部類,它可以不依賴於外部類例項被例項化。而通常的內部類需要在外部類例項化後才能例項化,其語法看起來挺詭異的,如下所示。 1 2 3 4 5

Java的部類Inner Class和巢狀類Nested Class的區別

內部類是類中類(內部類不為同一包的其他類可見,具有很好的封裝性),分為靜態內部類,成員內部類,區域性內部類以及匿名內部類;區域性內部類寫在方法裡面;用到最多的就是匿名內部類,例子如下: 首先定義一個介面:Interface A{ public void method();}