【JavaSEノート】対象(四)インタフェース

15415 ワード

今期の知識点:
インタフェース内部のクラス形式パラメータと戻り値の問題
1.インタフェース
a.概要:Cat,Dogなどの動物類の具体的な動物.高跳びなどの余分な動作がある場合があります.これらのアクションは特定のクラスに定義できないため、Javaはこの場合にキーワードinterfaceインタフェースを提供します.
b.インタフェースの定義形式:
i.クラス/インタフェースの命名規則:
1)単語:最初の文字を大文字にする
2)複数の単語:各単語の頭文字が大文字
ii. 書式:
インターフェース名{
……
}
c.インタフェースの特徴:
i.方法:
インタフェースで定義されている方法は抽象的な方法しかありません★
インタフェースに構築方法がありません
ii. インタフェースのサブクラスとインタフェースの関係:
1)実現関係:
implements
サブクラスimplementsインタフェース{
}
2)抽象的なサブ実装クラスは,インスタンス化できないため意味がない.
3)非抽象的なサブインプリメンテーションクラスは,インスタンス化可能である.
4)インタフェースのサブインプリメンテーションクラスを用いて実力化する必要がある:
AnimalPlay a = new Cat();
例:
				interface AnimalWay{
					public abstract void play();
				}
				abstract class Animal{
					
				}
				class Cat extends Animal {
					
				}
				class PlayCat extends Cat implements AnimalWay{
				
					@Override
					public void play() {
						System.out.println("Cat play ball.");
						
					}
					
				}
				public class Demo01 {
					public static void main(String[] args) {
						AnimalWay a = new PlayCat();
						a.play();
					}
				}
				
				//out:
				Cat play ball.

d.(面接問題)インタフェースと抽象類の違いは?
i.メンバーの違い:
1)インタフェース:
a)メンバー変数:定数のみ、デフォルトの修飾子:public static final.
b)構築方法:インタフェースに構築方法がない.
c)メンバーメソッド:抽象メソッドのみ、デフォルトの修飾子:public abstract.
2)抽象類:
a)メンバー変数:定数でも変数でもよい.
b)構造方法:有参構造であってもよいし、無参構造であってもよい.データを初期化します.
c)メンバーメソッド:抽象メソッドがあってもよいし、非抽象メソッドがあってもよい.
ii. 関係の違い:
1)クラスとクラスの関係:継承(extends)、単一継承、多継承できない
2)インタフェースとインタフェースの関係:継承(extends)、単独で継承してもよいし、複数で継承してもよい
3)クラスとインタフェースの関係:実装(implements)は,単一実装でも多実装でもよい.また、1つのクラスが別のクラスを継承しながら複数のインタフェースを実現することができます!
iii.設計理念の違い:
1)継承はis aの関係を体現し,継承によって保証される.
2)インタフェースはlike aの関係を体現し,インタフェース多態の拡張機能である.
例:
			interface Inter{
				int a=10;
				public final int b =20;
				public static final int c =30;
				public abstract void show();
			}
			class A implements Inter{
			
				@Override
				public void show() {
					System.out.println(a);
				}
				
			}
			public class Demo02 {
				public static void main(String[] args) {
					Inter i = new A();
					System.out.println(Inter.a);
					System.out.println(Inter.b);
					System.out.println(Inter.c);//       static  ,      ,     
				}
			}
			//out:
			10
			20
			30

e.クラスとクラス、クラスとインタフェース、インタフェースとインタフェースの関係:
i.クラスとクラス:関係を継承する.単に継承することはできますが、多く継承することはできません.
ii. クラスとインタフェース:関係を継承します.単に継承することができて、多く継承することができます.
iii.インタフェースとインタフェース:実装関係は、単に実装してもよいし、複数実装してもよいし、1つのクラスを継承しながら複数のインタフェースを実装してもよい.
f.猫犬ケース(インタフェース付き)
猫と犬のケースは、遊びの追加機能を追加します.
分析:
猫:名前、年齢、色
有参/無参
メンバーメソッド:set()/get(),eat(),eat()
犬:名前、年齢、色
有参/無参
メンバーメソッド:set()/get(),eat(),eat()
独立したクラスを抽出する:動物クラス:抽象クラス:
有参/無参
メンバーメソッド:set()/get()
eat();抽象メソッド、eat()
猫と犬はそれぞれ自動物類を継承します.
一部の猫と犬は遊ぶ機能を持っています.
プレイインタフェースを定義するには:
一部の猫は猫から引き継いでインタフェースを実現します
一部の犬は猫から引き継いでインタフェースを実現します
解析:抽象化
実装:抽象から具体へ
			abstract class Animal2 {
				private String name;
				private int age;
				private String color;
			
				public Animal2() {
					super();
				}
			
				public Animal2(String name, int age, String color) {
					this.name = name;
					this.age = age;
					this.color = color;
				}
			
				public String getName() {
					return name;
				}
			
				public void setName(String name) {
					this.name = name;
				}
			
				public int getAge() {
					return age;
				}
			
				public void setAge(int age) {
					this.age = age;
				}
			
				public String getColor() {
					return color;
				}
			
				public void setColor(String color) {
					this.color = color;
				}
			
				public abstract void eat();
			
			}
			
			interface Playing {
				public abstract void paly();
			}
			
			class Cat2 extends Animal2 {
			
				public Cat2() {
					super();
				}
			
				public Cat2(String name, int age, String color) {
					super(name, age, color);
				}
			
				@Override
				public void eat() {
					System.out.println("Cat eat fish");
				}
			
			}
			
			class Dog2 extends Animal2 {
			
				public Dog2() {
					super();
				}
			
				public Dog2(String name, int age, String color) {
					super(name, age, color);
				}
			
				@Override
				public void eat() {
					System.out.println("Dog eat bone");
				}
			
			}
			
			class PlayCat2 extends Cat2 implements Playing {
			
				public PlayCat2() {
					super();
					// TODO Auto-generated constructor stub
				}
			
				public PlayCat2(String name, int age, String color) {
					super(name, age, color);
					// TODO Auto-generated constructor stub
				}
			
				@Override
				public void paly() {
					System.out.println("This cat like playing ball");
				}
			
			}
			
			class PlayDog2 extends Dog2 implements Playing {
			
				public PlayDog2() {
					super();
				}
			
				public PlayDog2(String name, int age, String color) {
					super(name, age, color);
				}
			
				@Override
				public void paly() {
					System.out.println("This Dog like playing cat");
				}
			
			}
			
			public class          {
				public static void main(String[] args) {
					PlayCat2 a = new PlayCat2("Tom",3,"yellow");
					System.out.println("name:" + a.getName() + " age:" + a.getAge() + " color:" + a.getColor());
					a.eat();
					a.paly();
					Animal2 b = new Cat2("Peter",3,"blue");
					System.out.println("name:" + b.getName() + " age:" + b.getAge() + " color:" + b.getColor());
					b.eat();
					
				}
			}
			//out:
			name:Tom age:3 color:yellow
			Cat eat fish
			This cat like playing ball
			name:Peter age:3 color:blue
			Cat eat fish

2.内部クラス
a.内部クラスの概要:
あるクラスに別のクラスが定義され、内部クラスと呼ばれます.
内部クラスと外部クラスは直接関係を継承していません!
例:AクラスにBクラスが定義されています.BはAクラスの内部クラスで、Aクラスは外部クラスと呼ばれています.
b.内部クラスのアクセス特徴:
内部クラスは、外部クラスのメンバー(プライベートを含む)に直接アクセスできます.
c.外部クラスは内部クラスのメンバーに直接アクセスできますか?
外部クラスは、内部クラスのメンバーに直接アクセスできません.
ここで内部クラスオブジェクトを作成し、内部クラスオブジェクトでメソッドを使用する必要があります.
例:
			class Out01{
				private int a = 10 ;
				
				class In01{
					public void fun(){
				//		               ,    !
						System.out.println(a);
					}
				}
				public void hun(){
					In01 s = new In01();
					s.fun();
				}
			}
			public class Demo01 {
				public static void main(String[] args) {
					Out01 a = new Out01();
					a.hun();
				}
			}
			//out:
			10

d.内部クラスの分類:
i.メンバー内部クラス:外部クラスのメンバーの場所.
ii. ローカル内部クラス:外部クラスのローカル位置.
例:
			class Out{
				private int num = 10 ;
				//    
				//     
				class In01{
					
				}
				public void fun(){
					//    
					//     
					class In02{
						
					}
				}
			}

e.メンバー内部クラス:
i.内部クラスへのアクセスのメンバーフォーマット:オブジェクトを直接作成することはできません.
書式:
外部クラス名内部クラス名オブジェクト名=外部オブジェクト.内部オブジェクト;
例:
				class Out03{
					private int a = 10 ;
					class In03{
						public void fun(){
							System.out.println(a);
						}
					}
					public void hun(){
						
					}
				}
				
				public class Demo03 {
					public static void main(String[] args) {
					//        :    .         =     .      ;
					//      Out03.In03 a = new Out03().In03();//    
						Out03.In03 a = new Out03().new In03();
						a.fun();
					}
				}

ii. メンバー内部クラスに関する修飾子:
1)private:データのセキュリティを保護することを目的としています.
2)メンバー内部クラスは、静的内部クラス、静的内部クラスがアクセスする外部データクラス、必要な静的であってもよい.
例:
					class Out04{
						private int a = 10 ;
						private static int b =20;
						
						public static class In04{
							public void fun(){
								System.out.println(b);
							}
							//    
							public static void hun(){
								System.out.println(b);
							}
						}
					}
					public class Demo04 {
						public static void main(String[] args) {
							Out04.In04 a = new Out04.In04();
							a.fun();
							a.hun();
						}
					}

iii.メンバーの静的内部クラスが自分のメンバーにアクセスする方法
1)メンバー内部クラスがprivateによって修飾されると,オブジェクトを直接作成することはできない.
この場合、静的メンバー内部クラスは、次の方法でこのクラスのメンバーにアクセスできません.
Out04.In04 a = new Out04().new In04();//エラーメソッド
2)内部メンバーへのアクセス方法
a)メンバー静的内部クラスアクセス内部クラスメンバーのアクセスフォーマット:
外部クラス名内部クラス名オブジェクト名=new外部クラス名.内部クラス名();
Out04.In04 a = new Out04.In04();
a.fun();
a.hun();
b)メンバー内部クラスに静的メソッドfun()がある場合、別の方法でアクセスすることができる.
Out04.In04.fun();
f.ローカル内部クラス
i.ローカル内部クラスのメンバーは、外部クラスのデータに直接アクセスできます.
ii. ローカル位置アクセスメンバー内部クラスのメンバーメソッド、ローカル内部クラスオブジェクトの作成、アクセスメソッド.
g.(面接問題)ローカル内部クラスアクセスローカル変数、何か要求がありますか?
i.要求:ローカル内部クラスはローカル変数にアクセスし、ローカルにfinal修飾を使用させる必要がある.
ii. 理由:ローカル変数はメソッドの呼び出しに伴って存在し、メソッドの呼び出しが完了するにつれて消失します.しかしすぐに消えることはなく,GCアイドル時にゴミ回収が行われるのを待つとfun()メソッド呼び出しは完了するが,ローカルクラスはまだアクセスしているので,その場合にはローカルをfinal修飾する必要がある.
例:
				class Out05{
					private int a =10;
					//       
					public void fun(){
						int b =20;		//    
						final int c =30 ;	//    ,         
						//     
						class In05{
							public void hun(){
								System.out.println(a);//       
				//			System.out.println(b);//  
								System.out.println(c);
							}
						}
						//  hun()  
						In05 d =new In05();
						d.hun();
					}
				}
				
				public class Demo05 {
					public static void main(String[] args) {
						//       
						Out05 a = new Out05();
						a.fun();
					}
				}

h.匿名内部クラス
i.前提条件:
1)クラスまたはインタフェースがあります.
2)このクラスは、特定のクラス/抽象クラスであってもよい.
ii. 書式:
新クラス名/インタフェース名(){
メソッドの書き換え
};
iii.匿名内部クラスの本質:
クラスを継承するか、インタフェースを実装するサブクラスオブジェクトが必要です.
例:
			interface Magic{
				public abstract void fun();
				public abstract void hun();
			}
			
			class Out06{
				public void gun(){
					Magic a=new Magic(){
			//     :         :
			//1)       :         
			//2)            
			
						@Override
						public void fun() {
							System.out.println("We have fun");
						}
			
						@Override
						public void hun() {
							System.out.println("We have hun");
						}
					};
					a.fun();
					a.hun();
				}
				
			}
			public class Demo06 {
				public static void main(String[] args) {
					Out06 a = new Out06();
					a.gun();
				}
			}
			//out:
			We have fun
			We have hun

i.(面接問題):コンソールでそれぞれ出力:30,20,10内部クラス外部クラスは継承関係がない.
Outerを使用してthisを限定します.
			class Outer8{
				public int num = 10 ;
				
				//     
				class Inner8{
					public int num = 20 ;
					
					public void method(){
						int num = 30 ;
						System.out.println(num);
						System.out.println(this.num); //        :Inner8  
			//		    System.out.println(new Outer8().num);//            num
						System.out.println(Outer8.this.num);//      .this       (     this)
						
					}
				}
			}
			//   
			public class InnerTest2 {
				public static void main(String[] args) {
					//             
					//    .         =    .      ;
					Outer8.Inner8 oi = new Outer8().new Inner8();
					oi.method();
				}
			}

3.形式パラメータと戻り値の問題
a.クラスは形式パラメータとして:(匿名オブジェクトが言及した)
		class Student{
			public void show(){
				System.out.println("Good Good Study,Day Day Up");
			}
		}
		class StudentDemo{
			public void method(Student s){
			//s =new Student(); Student s = new Student();
				s.show(); 
			}
		}
		//   
		public class StudentTest {
			public static void main(String[] args) {
				//  :    StudentDemo method  
				//1)  StudentDemo  
				StudentDemo sd = new StudentDemo() ;
				//2)  Student    
				Student s = new Student() ;
				//3)            
				sd.method(s);
				
				//    
				new StudentDemo().method(new Student());
			}
		}

b.抽象クラスは形式パラメータとして:抽象クラスは直接インスタンス化できず、抽象クラスのサブクラスオブジェクトが必要である.
次のコードは、直接使用できません.
Myのオブジェクト呼び出し
hun()は,中のパラメータが抽象クラスであり,抽象クラスは直接インスタンス化できないため,サブクラスをインスタンス化する必要がある.
		abstract class Fu{
			public abstract void fun();
		}
		class My {
			public void hun(Fu a){
				a.fun();
			}
		}
		//    
		class Son extends Fu{
			//        
			@Override
			public void fun() {
				System.out.println("I want something just like this!");
			}
			
		}
		public class Demo {
			public static void main(String[] args) {
				/*
				 *   :  My  hun()  
				 *      My      hun(),           ,           ,
				 *            
				 * */
				My a = new My();
				Fu f = new Son();
				a.hun(f);
			}
		}
		//out:
		I want something just like this!

c.インタフェースを形式パラメータとする
		//  
		interface Basic{
			public abstract void fun();
		}
		class Student3{
			//          ,          
			public void show(Basic a){
				a.fun();
			}
		}
		//                 
		class Student4 implements Basic{
		
			@Override
			public void fun() {
				System.out.println("I want something just like this!");
			}
			
		}
		public class Demo02 {
			public static void main(String[] args) {
				//  :  Student3  show()  
				//  Student3   
				Student3 a = new Student3();
				//      
				Basic b = new Student4();
				a.show(b);
			}
		}
		//out:
		I want something just like this!

d.クラスは戻り値タイプとしてそのクラスオブジェクトを返す
		class People02{
			public void fun(){
				System.out.println("Oh is Magic");
			}
		}
		class PeopleDemo02{
			public People02 hun(){
				return  new People02();
			}
		}
		public class Magic02 {
			public static void main(String[] args) {
				//    
				PeopleDemo02 a = new PeopleDemo02();
				//  a PeopleDeom02    
				People02 b = a.hun();
				b.fun();
				//    ,    。
				new PeopleDemo02().hun().fun();
			}
		}
		//out:
		Oh is Magic
		Oh is Magic

e.抽象クラスが戻り値として返されるのは、その抽象クラスのオブジェクト(インスタンス化できない)ではなく、抽象クラスのサブクラスオブジェクトを返す
		abstract class FuZe{
			public abstract void fun();
		}
		class You{
			public FuZe hun(){
			//	return new FuZe();//    
				return new Sun();//            
			}
		}
		class Sun extends FuZe{
		
			@Override
			public void fun() {
				System.out.println("I want something just like this!");
			}
			
		}
		public class          {
			public static void main(String[] args) {
				//  You  ,           
				You a = new You();
				FuZe b = a.hun();
				b.fun();
				//    
				new You().hun().fun();
			}
		}
		//out:
		I want something just like this!
		I want something just like this!

f.インタフェースが戻り値として返す必要があるのはインタフェースのサブインプリメンテーションクラスオブジェクトである
		interface jieKou{
			public abstract void fun();
		}
		class Student{
			public jieKou getIt(){
				return new Student2();
			}
		}
		class Student2 implements jieKou{
		
			@Override
			public void fun() {
				System.out.println("I want something just like this!");
			}
			
		}
		public class Demo01 {
			public static void main(String[] args) {
				new Student().getIt().fun();
			}
		}
		//out:
		I want something just like this!

g.まとめ:★★
i.形式パラメータ:
1)クラス名:クラスが必要なオブジェクト
2)抽象クラス名:クラスが必要なサブクラスオブジェクト
3)インタフェース名:当該インタフェースを必要とする実装クラスオブジェクト
ii. 戻り値のタイプ:
1)クラス名:クラスのオブジェクトを返します.
2)抽象クラス名:そのクラスのサブクラスオブジェクトを返す
3)インタフェース名:当該インタフェースの実装クラスのオブジェクトを返す
iii.チェーンプログラミング
1)対象.方法1().方法2()....方法n();
この使い方:実は方法1()の呼び出しが終わった後、1つのオブジェクトを必要とします;
メソッド2()呼び出しが完了したら、オブジェクトを返す必要があります.
メソッドn()の呼び出しが完了すると、オブジェクトであってもよいし、オブジェクトでなくてもよい.