Javaの概念「extends(継承)」の本質である、元の機能を1行も書き直さずに引き継ぎ、新しい処理を付け足してプログラムを進化させる構造をProcessingのキャンバス上に視覚化する。
どうも上達の研究家のワタタクです。
前回の記事(Javaの「extends」ってなに?クラスをパワーアップさせる「型抜き」の魔法を徹底解説!)
では、extendsの本質が「すでにある型をコピーして、最小限の追加コードでパワーアップ版を作るための優しい知恵」であることを解説しました。
今回はLinked Logカテゴリーとして、「ベースとなる親クラスの遺伝子をそのまま受け継ぎ、extendsの光のラインを通って、新しい機能を纏った拡張型の子クラスへと美しく進化する世界」をProcessingのコードで表現してみました!
「親のコードは書いていないのに、裏側で自動的に引き継がれている」というオブジェクト指向の最大の武器が、一発で脳にマッピングされるコードと設計図を共有します。
この記事を書いた人


上達の研究家 / アーティスト
「才能」ではなく「発見」で描く。文系・36歳からの上達ハック。
- ゼロから独学でクリエイティブコーディングに挑戦し、以下の実績を達成
- 開始1年8ヶ月目までに公募6つに挑戦し、3つ入選(勝率50%)
- KITTE大阪の18メートルあるAxCROSS大型スクリーン
- 虎ノ門ヒルズステーションタワーB2F TOKYO NODE エントランスサイネージで展示
- UN:O(東京大手町)にある会員限定のサテライトオフィスにて2作品常設展示
- 開始1年8ヶ月目までに公募6つに挑戦し、3つ入選(勝率50%)
- 開始1年9ヶ月目に、虎ノ門ヒルズ49階、地上250mのインフィニティプールへ作品提供・展示
- 実際の展示作品と動画、音楽やSEOでの実績はポートフォリオに載せております→https://my-portfolio-blue-three-63.vercel.app/works
脳内をビジュアライズするための設計思想
Javaの public class NeonParticle extends Particle という構造をグラフィックに翻訳するため、以下の3つのギミックを仕込みました。
1. 「通常形態(親)」と「進化形態(子)」の対比
画面の左側にベースとなる「親クラス(Particle)」のステージ、右側にそれを拡張した「子クラス(NeonParticle)」のステージを配置。何が引き継がれ、何が新しく追加されたのかをひと目で比較できるレイアウトにしました。
2. 遺伝子を引き継ぐ「extendsの光の架け橋」
左の親クラスから右の子クラスへ向けて、サイバー調のグラデーションライン(extends の架け橋)を伸ばしました。画面をクリックすると、親が持つ「座標や移動(move)」の情報が光のパルスとして右側へと受け継がれていくアニメーションを実装しました。
3. スーパークラスの動き + 新機能(flash)の融合
右側の子クラスのエリアでは、左側の親と全く同じ動き(move)を引き継いでつぶつぶが動き回ります。さらに、子クラスで新しく追加された独自の命令(flash)によって、周囲に激しいネオンのエフェクトを纏って黄金に輝く「進化モード」に変身する演出を設計しました。
Processing実装コード
実行すると、extendsの進化システムがサイバー調のグラフィックとして立ち上がります。
実行結果。


// ==========================================
// 知識を視覚化する:Javaの「クラスの継承(extends)」
// (マウスクリックで引き継ぎパルス&デスクトップ自動保存)
// ==========================================
PFont jpFont;
float angle = 0;
float pulseX = 250; // パルスの初期位置
boolean isExtending = false;
// 親クラス(ベース)のつぶつぶデータ
float parentY = 300;
float parentSpeed = 2;
void setup() {
size(1200, 600);
// フォント生成は最初の一回だけ(setup内)にデプロイしてメモリを最適化
jpFont = createFont("Meiryo", 24, true);
textFont(jpFont);
}
void draw() {
background(16, 20, 30); // ディープサイバー背景
angle += 0.05;
// タイトル共通設定
textSize(24);
textAlign(CENTER, TOP);
fill(245);
text("【継承(extends)の世界】\n過去の資産をそのまま引き継ぎ、最小限のコードで新しい能力へ進化させる", width / 2, 30);
// 階層構造のベース(パッケージ)を薄く表示
textSize(12);
fill(100, 110, 130, 80);
textAlign(LEFT, TOP);
text("📦 package net.watataku.art;", 50, 90);
// 親のつぶつぶの移動処理(この動きが子にも引き継がれる)
parentY += parentSpeed;
if (parentY < 230 || parentY > 410) {
parentSpeed *= -1;
}
// -------------------------------------------------------------
// 左側:スーパークラス(親クラス:Particle)
// -------------------------------------------------------------
stroke(52, 152, 219, 120); // 親のイメージカラー:青
strokeWeight(2);
fill(25, 30, 45);
rect(80, 140, 340, 340, 12);
fill(52, 152, 219);
textSize(16);
textAlign(LEFT, TOP); // 文字の位置基準を左上に統一
text("👨👦 スーパークラス (親クラス)", 100, 160);
textSize(20);
text("public class Particle", 100, 190);
// 親の持つメンバー(データと機能)
textSize(13);
fill(150);
text("・int x, y; (座標のデータ)", 110, 240);
text("・void move(); (移動する処理)", 110, 265);
// 親のつぶつぶグラフィック(通常の青い光)
drawBasicParticle(250, parentY, color(52, 152, 219));
// -------------------------------------------------------------
// 中央:extends という名の「進化の架け橋」
// -------------------------------------------------------------
strokeWeight(3);
stroke(155, 89, 182, 80); // 継承の紫ライン
line(420, 310, 780, 310);
fill(155, 89, 182);
textSize(15);
textAlign(CENTER, BOTTOM);
text("extends (引き継ぎ&拡張)", 600, 295);
// マウスクリックで走る遺伝子パルスのアニメーション
if (isExtending) {
pulseX += 8;
if (pulseX > 780) {
pulseX = 250;
isExtending = false;
}
noStroke();
fill(255, 255, 200, 200);
// 【バグ修正完了】引数を仕様通りの5つにリファクタリング!
ellipse(pulseX, lerp(parentY, 310, map(pulseX, 250, 420, 0, 1)), 12, 12);
}
// -------------------------------------------------------------
// 右側:サブクラス(子クラス:NeonParticle)
// -------------------------------------------------------------
stroke(241, 196, 15, 120); // 子のイメージカラー:ゴールド
strokeWeight(2);
fill(28, 33, 48);
rect(780, 140, 340, 340, 12);
fill(241, 196, 15);
textSize(16);
textAlign(LEFT, TOP);
text("🚀 サブクラス (子クラス)", 800, 160);
textSize(20);
text("class NeonParticle extends Particle", 800, 190);
// 子の持つメンバー(引き継ぎと追加)
textSize(12);
fill(100);
text(" (親から自動コピー) ➔ int x, y;", 810, 240);
text(" (親から自動コピー) ➔ void move();", 810, 265);
fill(241, 196, 15);
textSize(13);
text("★ void flash(); (新しく追加した光る処理)", 810, 295);
// 子のつぶつぶグラフィック(親のmoveを引き継ぎつつ、独自のflashを纏う)
drawNeonParticle(950, parentY, color(241, 196, 15));
// -------------------------------------------------------------
// 下部:Javaのルール解説表示
// -------------------------------------------------------------
textSize(14);
textAlign(CENTER, TOP);
fill(180);
text("👉 子クラスの中には x や y、move() のコードを1行も書いていません!", width / 2, height - 85);
fill(241, 196, 15);
text("extends と書くだけで親の遺伝子を100%引き継ぎ、新しい能力(flash)だけを追加できる!", width / 2, height - 60);
// 操作案内表示
fill(110);
textSize(11);
text("💡 画面をクリックすると、遺伝子パルスが走り、デスクトップに実行結果が画像で保存されます", width / 2, height - 20);
}
// 親の通常つぶつぶを描画
void drawBasicParticle(float x, float y, color c) {
pushMatrix();
translate(x, y);
noStroke();
fill(c, 50);
ellipse(0, 0, 25, 25);
fill(255);
ellipse(0, 0, 10, 10);
popMatrix();
}
// 子のネオン進化つぶつぶを描画(独自のflashメソッドの視覚化)
void drawNeonParticle(float x, float y, color c) {
pushMatrix();
translate(x, y);
// flash(); メソッドによる激しいネオンフラッシュエフェクト
float flashSize = (sin(angle * 3) + 1) * 20 + 30;
noStroke();
for (int i = 3; i > 0; i--) {
fill(red(c), green(c), blue(c), 35 - i*8);
ellipse(0, 0, flashSize + i*15, flashSize + i*15);
}
fill(c, 150);
ellipse(0, 0, 25, 25);
fill(255);
ellipse(0, 0, 12, 12);
popMatrix();
}
// マウスクリックでアニメーション始動&デスクトップへ自動保存
void mousePressed() {
isExtending = true;
pulseX = 250; // パルスリセット
// デスクトップ自動保存処理
String desktopPath = System.getProperty("user.home") + "/Desktop/";
String timestamp = nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
String fileName = "extends_evolution_" + timestamp + ".png";
save(desktopPath + fileName);
println("デスクトップに保存しました: " + fileName);
}コード表現に落とし込んでみて気づいたこと
Javaの extends という機能を、ただの「テキストのコピペ代行」として覚えるのではなく、Processingの「左の動きを右の座標(parentY)へそのまま流用しつつ、追加のエフェクト(flashSize)を重ねる構造」に翻訳したことで、継承の本質が完璧に腑に落ちました。
子クラスの描画関数である drawNeonParticle を書くとき、引数に親と同じ parentY をそのまま渡すだけで、自動的にシンクロして動き回る。このコードの挙動そのものが、Javaの「親のメソッドをそのまま使える」という仕様の縮図になっているんですね。
クリックした瞬間に紫のライン上を光のパルスが走り、右側の子クラスが激しく明滅(flash)し始める様子は、まさにプログラムの遺伝子が進化を遂げた瞬間のようで、動かしていて最高にワクワクするLinked Logになりました。
皆さんもぜひ、手元でこの進化の架け橋を動かして、Javaの効率的で美しい設計の思想を体感してみてください!
それでは今日もレッツワクワクコーディング。
関連記事



