Objective-C 初期化,オーバライド,self,super 【初級編 第7回】

この記事は2012年10月6日に書かれたものです。内容が古い可能性がありますのでご注意ください。


Objective-C 初期化,オーバライド,self,super 【初級編 第7回】

さて前回のコードで新たに人を表すクラスを作成し、属性として身長と体重を保持するにようにしました。
そしてそれらの属性にアクセスするためにアクセサというメソッドを用意して、値を設定していました。
では身長と体重の設定を行わなかったらどうなるでしょうか。
試してみましょう。

前回のコードの「main.m」ファイルの7,8行目をコメントアウトして下さい。
「//」をつけるとその行の設定した位置より後ろ側の部分がコメント行と解釈され、プログラムとみなされなくなります。


1つ目のメッセージ式の結果は「nan(not a number)」で演算結果が不正な値となっていることを示しています。
2つ目のメッセージ式の結果は0.0となっています。

なぜこんな結果となってしまったのかというとObjective-Cでは変数を作成し領域が確保されると
初期値として「0」が設定されます。計算している箇所でそれぞれの変数を0に置き換えてみると
BMI値の計算の方は「0/0*0」となり、無限大となってしまいます。それで「nan」となりました。
2つ目のメッセージ式の方は掛け算のみなので「0.0」となっています。

一応、変数には初期値として「0」が設定されますが、今回のように計算結果が不正な値となってしまう場合があります。
0での初期化が好ましくない場合は、変数を使用する前にその値をあらかじめ設定しておくか、
インスタンスが作成された時に初期値を設定しておく必要があります。
変数使用の前に値を設定するのは前回のセッターでできますね。なので今回はインスタンスが作成された際に
初期化するコードを付け加えてみます。
付け加える前にここまでに出てきたファイルを整理しておきます。

  • Bmi計算をするクラスを定義してある「Bmi.m」とその実装である「Bmi.m」
  • 人を表すクラスを定義してある「Person.h」とその実装である「Person.m」
  • メイン処理をする「main.m」

今回付け加えるのは人を表すクラスの部分です。

Person.mファイル

#import "Person.h"

@implementation Person
    -(id)init{
        self = [super init];
        if(self != nil){
            weight = 65;
            height = 1.71;
        }
        return self ;
    }

    -(double)weight{
        return weight;
    }
    -(void)setWeight:(double)personWeight{
        weight = personWeight;
    }
    -(double)height{
        return height;
    }
    -(void)setHeight:(double)personHeight{
        height = personHeight;
    }
@end

main.mファイル

#import <objc/Object.h>
#import "Bmi.h"
#import "Person.h"

int main(void){
    id mine = [[Person alloc] init];
    //[mine setWeight:55];
    //[mine setHeight:1.72];
    printf("%2.1fn",[Bmi calcBmi:[mine weight] height:[mine height]]);
    printf("%2.1fn",[Bmi calcProperWeight:[mine height]]);
  [mine free];
    return 0;
}

まず「Person.m」ファイルの方ですが、4行目~11行目の部分が付け加わったところです。
「-(id)init」というメソッドが新たにできています。このメソッド「Person.h」では定義していませんが、
その継承元である「Object.h」で定義されています。第3回目の記事で「Object.h」の一部が載せてあるので、
それを見てもらうとその中にインスタンスメソッド(頭に「-」ついてますよね)として「-init」が
定義されているのがわかると思います。このメソッドはインスタンスメソッドを初期化するためのものと
して用意されています。

初期化するメソッドが用意されているなら、これをそのまま使ってしまえばいいのではないかと思われるかもしれませんが、
あくまで「Object.h」での初期化処理なので、それを継承して使用する側(今回はPersonクラス)で新たに登場した
「weight」や「height」の初期化に関してはあずかり知らぬところとなります。
そこで新たに処理を付け加えているのが今回追加されている部分になります。このとき元々定義されている「init」メソッドと
同じ戻り値、引数のメソッドで実装を行っています。つまり元々の「init」を上書きしているわけですね。
こういうのをオーバライド(override)といいます。

ページ:

1

2
  • このエントリーをはてなブックマークに追加

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

PAGE TOP