アプリ版:「スタンプのみでお礼する」機能のリリースについて

初心者なのですが困っています。

以下のコードを実行したとき、実行例が表示されるように必要なクラスを作成せよ。
また、それらをカプセル化し、それを使用するよう以下のコードを修正せよ。カプセル化に関わる部分以外修正しないこと。

public class sanple{
public static void main(String[] args){
Employee[] emp=new Employee[4];
emp[0]=new Shain();
emp[0]=new Kacho();
emp[0]=new Bucho();
emp[0]=new Syacho();
for(int i=0;i<imp[i].length;i++){
System.out.println(emp[i].grade+":"+emp[i].salary);
}
}
}

かなり困ってます。どうか回答お願いします。

A 回答 (6件)

よく問題を見たら、「カプセル化に関わる部分を修正せよ」とありますね。


では、回答例として。

public class Employee {
    private String grade; ----------------- (1)
    private int salary;
    
    public String getGrade() { ------------- (2)
        return grade;
    }

    public int getSalary() {
        return salary;
    }

    protected void setGrade(String grade) { -----(3)
        /* 必要ならここでチェックを入れる */
        this.grade = grade;
    }

    protected void setSalary(int salary) {
        /* 必要ならここでチェックを入れる */
        this.salary = salary;
    }

}


public class Shain extends Employee {
    Shain(){
        setGrade("社員");
        setSalary(20000);
    }
}


public class Sample{
    public static void main(String[] args){
        Employee[] emp = new Employee[4];

        emp[0]=new Shain();
        emp[1]=new Kacho();
        emp[2]=new Bucho();
        emp[3]=new Syacho();

        for(int i = 0 ; i < emp.length ; i++ ) { -------------(ex)
            System.out.println(emp[i].getGrade()+":"+emp[i].getSalary()); --(4)
        }
    }
}

出題者の意図としてはこんな回答を期待してるんじゃないでしょうかねぇ。


不親切な解説をします。
(1) private で、このクラス以外からは手を出せないようにする。
(2) public のメソッドを用意することで、外部から値を取り出すことだけはできるようにする。
(3) 値設定のメソッドを protected にすることで、同一クラス、同一パッケージ、子孫クラスからの値設定を許可する。
(4) 直接メンバ変数を参照していたものを、メソッドを介して取得するように変更。
(ex) 問題の本質と関係なさそうな間違いがあったので、直しました。

何カ所か修正してあるので、そのまま出すとバレるかも知れないですよ。


ところで、何人かの方がすでにヒントや解答を示されています。
public とか protected とか abstruct とか enum とか、いろいろと細かいところが違いますよね。
これは「同じものでも人によって作り方が違うから」というよりも、想定している状況が違うからです。
このメンバ変数はどこまで見せるのか、このメソッドはどこまで共通なのか、このクラスのインスタンス生成は意味を成すのか。
それぞれの方がそれぞれに方針を決めているので、それぞれのソースができあがっているのです。
だから、誰のものがいちばん良いということはありません。
良さそうな所をツギハギするのも意味がないです。

どんなソースができるかは、どんな設計にするかで決まります。
ですから、これらのソースを見て、「これが答えだ」なんて思わないでください。
「ソースに込められた思想」を読み取って欲しいと切に願います。
    • good
    • 0

public class sanpleに間違いがあるような気がするので、もう一度確認してあげてもらえませんか?


特に、
>System.out.println(emp[i].grade+":"+emp[i].salary);
の部分が
System.out.println(emp[i].grade()+":"+emp[i].salary());
なんじゃないかと思うんです。
カプセル化の割に直接メンバ変数をアクセスさせていて、それじゃカプセル化じゃないよ、と突っ込みたくなるのですが。
    • good
    • 0

実にイジワルな課題ですね。



・Employee というクラスを継承しなければならない。
  =>言われなくても「継承」が必要だということがわかってないといけない。
・カプセル化しないといけない。
  =>カプセル化がわかってないといけない。
・カプセル化に関わる部分以外修正しないこと。とあるが、mainメソッドにも問題がある。
 4つの行で明らかなマチガイがあります。 (関係ないが、sanpleという英語からして「もしかして:」って感じです。)
=>実際に実行確認するために、コード修正が必要。

#2さんがいいとことまでヒントをくれていますが、たぶんこの課題の目的は、
"「カプセル化」したクラスの作成と、その呼び出し"
というなので、
emp[i].grade の部分なんか、Shainクラスのフィールドに直接アクセスするのではなく、
「カプセル化」されたクラスとして、Shainクラスに、gradeの値を返却するpubulicな"メソッド"を
用意して、そのメソッドを呼ぶことにより、値を取得せねばなりません。
emp[i].getGrade() みたいに。
そのため、クラスの書き方も一から考え直さなくてはいけません。

// Employeeクラス(抽象クラス)
abstract class Employee{
private String grade ="";
private String salary ="";
public String getGrade(){
return grade;
}
public String getSalary(){
return salary;
}
}

// Employeeクラスを継承したShainクラス
// ※同様に、Kacho、Bucho、Syachoクラスの作成も必要です。
class Shain extends Employee{
private String grade = "社員";
private String salary = "200000円";
Shain(){
System.out.println("理解するまで提出してはダメです");
}
public String getGrade(){
return grade;
}
public String getSalary(){
return salary;
}
}

//修正後のメインクラス

public class sample {
public static void main(String[] args) {
Employee [] emp = new Employee[4];
emp[0]=new Shain();
emp[1]=new Kacho();
emp[2]=new Bucho();
emp[3]=new Syacho();
for(int i=0;i<emp.length;i++){
System.out.println(emp[i].getGrade() +":"+emp[i].getSalary());
}
}
}
ってな感じでしょうか。
クラスの継承、カプセル化、カプセル化する理由について、
本などを理解できるまでじっくり読んでみてください。
ちなみに、このコード、そのままコピペして提出すると
ダメなメッセージがでるようにしときました。(w
    • good
    • 0

abstract class Employee {


//社員クラス
static enum 役職 {
平社員,係長,課長,部長,専務,社長;
}
static protected long seq = 0;

protected String name; //名前
protected long id; //社員番号
protected 役職 grade; //役職
protected int salary; //給与
protected int allowance;//手当


public Employee(){}
public Employee(String name){
this.name = name;
this.id = ++seq;
}

abstract String getGrade();
abstract int getSalary();

void print(){
System.out.println("  名前:" + name);
System.out.println("社員番号:" + id);
System.out.println("  役職:" + grade);
System.out.println("  給料:" + this.getSalary());
}
}

class Shain extends Employee{
public Shain(String name, int salary){
super(name);
grade=役職.平社員;
this.salary=salary;
}
public String getGrade(){
return "社員";
}
public int getSalary(){
return salary + allowance;
}
}
class Kacho extends Employee{
public Kacho(String name, int salary){
super(name);
grade=役職.課長;
this.salary=salary;
}
public String getGrade(){
return "課長";
}
public int getSalary(){
return salary + allowance;
}
}
class Bucho extends Employee{
public Bucho(String name, int salary){
super(name);
grade=役職.部長;
this.salary=salary;
}
public String getGrade(){
return "部長";
}
public int getSalary(){
return salary + allowance;
}
}
class Syacho extends Employee{
public Syacho(String name, int salary){
super(name);
grade=役職.社長;
this.salary=salary;
}
public String getGrade(){
return "社長";
}
public int getSalary(){
return salary + allowance;
}
}

public class Sample {
public static void main(String[] args){
Employee[] emp = new Employee[4];
emp[0]=new Shain("小澤 マリア", 200000);
emp[1]=new Kacho("高井 桃" , 300000);
emp[2]=new Bucho("水嶋 彩" , 400000);
emp[3]=new Syacho("笠木 忍" , 500000);
for(int i=0;i<emp.length;i++){
System.out.println(emp[i].getGrade() + ":" + emp[i].getSalary()+ "円");
// emp[i].print();
}
}
}
    • good
    • 0

emp[0]=new Shain();


のようになっているから、
Shain、Kacho, Bucho, Syacho クラスは、Employee クラスを継承する必要があります。

また、
emp[i].grade+":"+emp[i].salary
となっているから、 employee クラスにgrade、salary というフィールドが (恐らく) public で宣言されている必要があります。
派生クラスのコンストラクタ内で、基底クラスのフィールドを初期化するために基底クラスのパラメータを持ったコンストラクタを呼び出します。

例えば以下のような感じ。

class Employee{
public String grade;
public int salary;
public Employee(String sVal, int iVal){
grade = sVal;
salary = iVal;
}
}

class Shain extends Employee{
public Shain (){
super("社員", 200000);
}
}

残りの Kacho, Bucho, Shacho クラスも Shain クラス同様に作成します。
後は自力で・・・・・。
    • good
    • 0

実行例を補足してもらわんと回答者にはわからんのではないでしょうか



imp[i] が明らかに誤りだと思えるけど、カプセル化に関わる部分でないので修正できない。
なので、正しく実行させることはできない。

この回答への補足

回答例は、
社員:200000円
課長:300000円
部長:400000円
社長:500000円

と出力させたいのですが出来ません。

補足日時:2006/10/14 17:38
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!