質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

5回答

1569閲覧

javaクラスの初歩的な質問

uer03108

総合スコア194

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2017/09/20 05:45

編集2017/09/20 08:52

下記の様なクラスがあった場合、javaならではの(?)スマートな書き方ってあるのでしょうか。
funcPre関数の重複を簡略化できるのかなと言う質問になります。

class Sample{ public void funcA(int n){ funcPre(); //処理 } public void funcB(int n){ funcPre(); //処理 } public void funcC(int n, int m){ funcPre(); //処理 } public void funcD(int n){ //処理 } //前処理 private void funcPre(){ //処理 } }

追記
多くのご回答有難うございました。
勉強になります。

記述が重複する部分をprivate関数に置き換えていると、今度は関連性のないprivate関数が増えていって、その部分が読みにくくなると思って、質問させて頂きました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2017/09/20 05:47

そうしたい目的を具体的に記載いただけると助かります。
coco_bauer

2017/09/20 07:11

funcPre関数で処理されるコードは、funcPre関数の定義の中にだけ存在するので重複(同じ処理をするコードが複数の関数の中に出現)はありません。その意味でSlimなコードになっています。
swordone

2017/09/20 15:47

構成を考え直すことも視野に入れるべきでは?具体的にどのような処理になるのでしょうか?
guest

回答5

0

もっとコードが具体的になれば違った回答もあるかもしれませんが、質問文にあるコードで十分簡潔だと考えてよいです。

記述が重複する部分をprivate関数に置き換えていると、今度は関連性のないprivate関数が増えていって、その部分が読みにくくなると思って、質問させて頂きました。

private メソッドが互いに関連性がない(=独立している)方がよりよいコードと言えます。
public メソッドから利用する場合に private メソッドの呼び出し順やフィールドの状態に注意しなければならないとすると、より悪い状況におちいっています。

private メソッドが単純に多い場合は別のクラス(=責務)へと切り出せないか検討するとよいでしょう。

投稿2017/09/20 11:26

koko_u

総合スコア936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

momon-ga

2017/09/20 11:44

「別のクラス(=責務)へと切り出せないか検討」の雰囲気的を感じます
guest

0

Java

1public abstract class Sample { 2 3 private void preFunc(){ 4 //処理 5 } 6 7 protected abstract void func(); 8 9 public void do() { 10 preFunc(); 11 func(); 12 } 13} 14 15class SampleA extends Sample { 16 private int n; 17 18 public SampleA(int n) { 19 this.n = n; 20 } 21 22 @Override 23 protected void func() { 24 //処理 25 } 26} 27 28class SampleB extends Sample { 29 private int n; 30 31 public SampleB(int n) { 32 this.n = n; 33 } 34 35 @Override 36 protected void func() { 37 //処理 38 } 39} 40 41class SampleC extends Sample { 42 private int n; 43 private int m; 44 45 public SampleC(int n, int m) { 46 this.n = n; 47 this.m = m; 48 } 49 50 @Override 51 protected void func() { 52 //処理 53 } 54} 55 56class SampleD extends Sample { 57 private int n; 58 59 public SampleD(int n) { 60 this.n = n; 61 } 62 63 @Override 64 protected void func() { 65 //処理 66 } 67 68 @Override 69 public void do() { 70 func(); 71 } 72} 73 74public class Main { 75 public static void main(String[] args) { 76 Sample sampleA = new SampleA(1); 77 sampleA.do(); 78 79 Sample sampleB = new SampleB(1); 80 sampleB.do(); 81 82 Sample sampleC = new SampleC(1,2); 83 sampleC.do(); 84 85 Sample sampleD = new SampleD(1); 86 sampleD.do(); 87 } 88}

す、すまーと

投稿2017/09/20 06:38

abs123

総合スコア1280

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

目的に沿ったものではないかもしれませんがコンストラクタで呼ぶのはどうでしょうか。

Java

1class Sample{ 2 3 public Sample(){ 4 funcPre(); 5 } 6 7 public void funcA(int n){ 8 //処理 9 } 10 11 public void funcB(int n){ 12 //処理 13 } 14 15 public void funcC(int n, int m){ 16 //処理 17 } 18 19 public void funcD(int n){ 20 //処理 21 } 22 23 //前処理 24 private void funcPre(){ 25 //処理 26 } 27}

funcD()を使う場合にもfuncPre()が呼び出されてしまうという点が許容できるのであれば ですが。。。

投稿2017/09/20 06:10

Clor

総合スコア883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

よくわかりませんが、たとえばこういうのですか (未検証)。

java

1class Sample { 2 class Action { 3 public void exec() { 4 funcPre(); 5 doExec(); 6 } 7 protected void funcPre(){ 8 //処理 9 } 10 abstract public void doExec(); 11 12 } 13 class ActionA extends Action { 14 public void doExec() { 15 // 処理 16 }; 17 public setArgs(int n) { 18 this.n = n; 19 return this; 20 } 21 } 22 23 public void funcA(int n){ 24 return new ActionA().setArgs(n).exec(); 25 } 26 27 public void funcB(int n){ 28 return new ActionB().setArgs(n).exec(); 29 } 30 31 public void funcC(int n, int m){ 32 return new ActionC().setArgs(n, m).exec(); 33 } 34 35 public void funcD(int n){ 36 //処理 37 } 38}

投稿2017/09/20 06:10

unau

総合スコア2468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uer03108

2017/09/21 05:04

有難うございました。 こういうのです。 クラスを書けばよいのですね。 助かりました。
guest

0

ベストアンサー

Javaならでは…
Javaの標準機能だけでは無理なのですが、スマートな書き方であれば、AspectJ5によるアノテーション記法でしょうか。

以下のサンプルコードを動かすにはaspectjrtとaspectjweaverのライブラリが必要なので、少し難しいです。

Java

1import org.aspectj.lang.JoinPoint; 2import org.aspectj.lang.annotation.Aspect; 3import org.aspectj.lang.annotation.Before; 4 5// @Aspectを書いたクラスはAspectJのコンパイル対象クラスとなり、@Beforeなどが使えるようになる 6@Aspect 7public class Sample { 8 9 public void funcA(int n) { 10 //処理 11 System.out.println("funcA " + n); 12 } 13 14 public void funcB(int n) { 15 //処理 16 System.out.println("funcB " + n); 17 } 18 19 public void funcC(int n, int m) { 20 //処理 21 System.out.println("funcC " + n + " " + m); 22 } 23 24 public void funcD(int n) { 25 //処理 26 System.out.println("funcD " + n); 27 } 28 29 // @Beforeの中に条件を書くと、条件に当てはまるメソッドの処理の前に呼び出してくれる 30 // callは「そのメソッドを呼び出したとき」という条件 31 // 条件の書き方はAspectJの仕様を参照してください 32 // 以下の条件の場合、funcA、またはfuncB、またはfuncCのときだけ実行される 33 @Before("call(void funcA(int))" 34 + " || call(void funcB(int))" 35 + " || call(void funcC(int, int))") 36 public void funcPre(JoinPoint joinPoint) { 37 // JoinPointは呼び出し元などの情報が入っている 38 39 System.out.println("funcPre"); 40 // このメソッド内でthisと書いても、funcAを呼んでいるインスタンスとは別物なので注意 41 // 以下のように呼び出し元インスタンスはgetTargetで得る 42 // Sample sample = (Sample) joinPoint.getTarget(); 43 } 44 45 public static void main(String[] args) { 46 Sample m = new Sample(); 47 m.funcA(0); 48 m.funcB(1); 49 m.funcC(2, 3); 50 m.funcD(4); 51 } 52} 53

Mavenを使えばAspectJを使ったコードを簡単にビルドできます。mavenを利用した場合のpom.xmlの参考です。

XML

1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>example</groupId> 5 <artifactId>aspectj</artifactId> 6 <version>1.0-SNAPSHOT</version> 7 <packaging>jar</packaging> 8 <properties> 9 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 10 <maven.compiler.source>1.8</maven.compiler.source> 11 <maven.compiler.target>1.8</maven.compiler.target> 12 13 <aspectj-maven-plugin.version>1.10</aspectj-maven-plugin.version> 14 <aspectj.version>1.8.10</aspectj.version> 15 </properties> 16 17 18 <build> 19 <plugins> 20 <plugin> 21 <artifactId>maven-compiler-plugin</artifactId> 22 <version>2.5.1</version> 23 <configuration> 24 <source>${maven.compiler.source}</source> 25 <target>${maven.compiler.target}</target> 26 </configuration> 27 </plugin> 28 <plugin> 29 <groupId>org.codehaus.mojo</groupId> 30 <artifactId>aspectj-maven-plugin</artifactId> 31 <version>${aspectj-maven-plugin.version}</version> 32 <configuration> 33 <complianceLevel>${maven.compiler.source}</complianceLevel> 34 <source>${maven.compiler.source}</source> 35 <target>${maven.compiler.target}</target> 36 </configuration> 37 <executions> 38 <execution> 39 <phase>process-sources</phase> 40 <goals> 41 <goal>compile</goal> 42 </goals> 43 </execution> 44 </executions> 45 </plugin> 46 </plugins> 47 </build> 48 49 <dependencies> 50 <dependency> 51 <groupId>org.aspectj</groupId> 52 <artifactId>aspectjrt</artifactId> 53 <version>${aspectj.version}</version> 54 </dependency> 55 56 <dependency> 57 <groupId>org.aspectj</groupId> 58 <artifactId>aspectjweaver</artifactId> 59 <version>${aspectj.version}</version> 60 </dependency> 61 </dependencies> 62 63</project>

投稿2017/09/20 08:44

編集2017/09/20 09:10
masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uer03108

2017/09/21 04:53

回答有難うございました。 便利なものがあるんですね。 これは@Beforeの関数に戻り値も設定できるのでしょうか。 グローバル変数を使用するとか??
masaya_ohashi

2017/09/21 05:19

えっと、funcPreでなにか結果を返したいということでしょうか?
uer03108

2017/09/21 05:30

はい。 List<Object> funcPre( ) などですが。 ・前処理の値を取得 ・関数内で処理(関数によって異なる) ・処理結果を後処理 といった関数を簡潔に書く方法を考えておりました。 前処理と後処理をprivate関数にしています。 private関数がゴチャゴチャ・・・と言った感じです。 複数ファイルに分けた方が良いかもしれません。
uer03108

2017/09/21 05:33

重ね重ね有難うございます。
masaya_ohashi

2017/09/21 06:15

一時変数を受け取らなければならない以上、省略することはできないかと思います…メンバ変数に一時的にキープしておくことは可能ですが、スレッドセーフなどを気にする必要が出てきます。とりあえず、メンバ変数に一時的に記憶する場合の処理を追記します。
masaya_ohashi

2017/09/21 06:17

と思ったのですが、まず具体的にやりたいことをコードにして例示してもらえませんか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問