2-static、接口、多态和内部类


目录

提示:这里介绍static、接口、多态和内部类的知识点;


提示:以下是本篇文章正文内容,下面案例可供参考

一、Static

概述:static是一个关键字,表示静态的意思,用来修饰成员变量,成员方法和代码块;

1、static修饰成员变量:

1、格式:
	修饰符 static 数据类型 变量名;
	public static   int    num;
2、访问方式:
	1、对象名.静态变量名;
	2、类名.静态变量名;---->推荐使用
3、特点:
	1、被static修饰的成员变量叫做静态成员变量或者类变量;
	2、被static修饰的成员变量会被该类的所有对象所共享;
	3、被static修饰的成员变量,如果被某一个对象修改后,
	   其他所有的对象访问到变量的值都是修改后的值;
	

2、static修饰成员方法:

1、格式:
	修饰符 static 返回值类型 方法名(形参列表){}
	public static    void   method(形参列表){}
2、访问方式:
	1、对象名.静态变量名;
	2、类名.静态变量名;---->推荐使用
3、静态方法调用的注意事项:
	1、静态方法中不能出现this关键字
	2、静态方法中只能访问静态成员变量和静态成员方法;
	3、静态方法中不能直接访问非静态的成员变量和成员方法;
	4、非静态方法中可以直接访问一切的成员变量和成员方法;

3、static修饰代码块:

1、格式:
	static{
		....
}
2、位置:类中方法外;
3、执行:
	1、随着类的加载而执行,并且只会执行一次;
	2、类的加载:第一次使用该类的时候,就会加载,并且只会加载一次;


案例:
public class Chinese { 
	static { 
		System.out.println("Chinese 静态代码块..."); 
	}
public Chinese(){ 
	System.out.println("Chinese 空参构造..."); 
	} 
} 
public class Test { 
	public static void main(String[] args) { 
		System.out.println("开始"); 
		Chinese c1 = new Chinese(); 
		Chinese c2 = new Chinese(); 
		System.out.println("结束"); 
	} 
}

二、接口

1.接口的概述:

概述:接口是Java语言中的一种引用类型,主要用来存储方法的;

1、格式:
	修饰符 interface 接口名{}
	public interface Fu{}
2、实现接口:
	修饰符 class 实现类  implements 接口{}
	public class  Impl  implements Fu{}
3、接口中的成员:
	1、常量---->jdk7及其以前出现
	2、抽象方法---->jdk7及其以前
	3、默认方法---->jdk8
	4、静态方法---->jdk8
	5、私有方法---->jdk9
4、定义接口需要使用interface关键字,编译后也会产生class文件
5、接口没有构造方法,也不能创建对象,所以一般只供实现类实现的,类似于继承
6、实现接口的类叫做实现类,如果实现类是一个普通类,则必须重写接口中的所有抽象方法,否则实现类是一个抽象类

2、接口中成员的访问特点:

接口中成员的访问特点:
	1、接口中常量:只要共接口名直接访问,也可以被实现类继承
	2、接口中的抽象方法:就是供实现类重写的
	3、接口中的默认方法:可以供实现类对象直接调用,或者被实现类重写
	4、接口中的静态方法:只供接口名直接访问,不可以被实现类继承
	5、接口中的私有方法:只能在接口内部方法中调用,不可以被实现类继承

案例:
public interface IA{
	//常量使用public static final修饰,可以省略
	public static final int num = 10;

	//抽象方法:使用public abstract修饰,可以省略
	public abstract void method1();

	//默认方法:使用public default修饰,不可以省略
	public default void method2(){
		sout("这是IA中的一个默认方法");
	}

	//静态方法:使用public static修饰,不可以省略
	public static void method3(){
		sout("这是IA中的一个静态方法...");
	}

	//私有方法:使用private修饰,不可以省略(私有方法只有在jkd9以上的版本才支持)
	private void method4(){
		sout("这是IA中的一个私有方法...");
	}
}

public class Imp implements IA{
	@Override
	public void method1(){
		sout("这是Imp类中的一个method1方法...");
	}
	
	@Override
	public void method2(){
		sout("这是Imp类中的一个method2方法....");
	}
}

public class Test { 
	public static void main(String[] args) { 
		 // 访问接口中的常量 
		 System.out.println(IA.NUM);// 10 
		 System.out.println(Imp.NUM);// 10 
		 // 访问接口中的抽象方法 
		 Imp imp = new Imp(); 
		 imp.method1();
		  // 访问接口中的默认方法 
		  imp.method2(); 
		  // 访问接口中的静态方法 
		  IA.method3(); 
	  } 
}


三、多态

1、概述:

1、多态是面向对象三大特征之一。
2、多态指对于同一行为,对于不同的对象,具有不同的表现形式。在程序中,表示对同一方法,不同
的对象有不同实现。
3、实现多态的前提条件:
	①、继承或者实现
	②、父类引用指向子类对象 eg: Fu f = new Zi();
	③、方法的重写(没有重写方法多态是没有意义的)
4、格式:
	父类的引用指向子类的对象:
		格式: 父类类型 变量名 = new 子类类型(实参);
		eg: 	Fu  f = new Zi();
	接口的引用指向实现类的对象:
		格式: 接口名 变量名 = new 实现类名(实参);
		eg: IA a = new Imp();

2、多态时访问成员的特点:

1.成员变量: 编译看左边(父类),运行看左边(父类)
2.非静态成员方法:编译看左边(父类),运行看右边(子类)
3.静态成员方法: 编译看左边(父类),运行看左边(父类)
  记忆: 除了非静态成员方法编译看左边,运行看右边,其余都看左边

案例:
class Fu{ 
	int num = 10; 
	public void method1(){ 
		System.out.println("Fu 非静态方法method1..."); 
	}
	public static void method2(){ 
		System.out.println("Fu 静态方法method2..."); 
	} 
}
class Zi extends Fu{ 
	int num = 20; 
	public void method1(){ 
		System.out.println("Zi 非静态方法method1..."); 
	}
	public static void method2(){
		System.out.println("Zi 静态方法method2..."); 
		} 
}
public class Test { 
	public static void main(String[] args) { 
		// 父类的引用指向子类的对象 
		Fu f = new Zi(); 
		System.out.println(f.num);// 10 
		f.method1();// Zi 非静态方法method1... 
		f.method2();// Fu 静态方法method2... 
	} 
}

3、多态的应用场景:

3.1、变量多态 -----> 意义不大

class Animal{ 
	public void eat(){ 
		System.out.println("吃东西..."); 
	} 
}
class Dog extends Animal{ 
	public void eat(){ 
		System.out.println("狗吃骨头..."); 
	} 
}
class Cat extends Animal{ }
public class Test { 
	public static void main(String[] args) { 
		// 父类的引用指向子类的对象 
		Animal anl1 = new Dog();
		// 变量多态 
		Animal anl2 = new Cat();
		// 变量多态 
		// 使用anl1变量一定要根据多态时成员访问特点去使用 
		anl1.eat();// 狗吃骨头... 
		} 
}

3.2、形参多态 -----> 常用

概述:参数的类型是父类类型,那么就可以接收该父类类型的对象以及该父类类型的所有子类
对象

class Animal{ 
	public void eat(){ 
		System.out.println("吃东西..."); 
	} 
}
class Dog extends Animal{
	public void eat(){ 
		System.out.println("狗吃骨头..."); 
	} 
}
class Cat extends Animal{ 
	public void eat(){ 
		System.out.println("猫吃鱼..."); 
	} 
}
public class Test { 
	public static void main(String[] args) { 
		Dog d = new Dog(); 
		method(d);// 狗吃骨头... 
		System.out.println("======"); 
		Cat c = new Cat(); method(c);// 猫吃鱼... 
	}
// 定义一个方法,既可以接收Dog对象也可以接收Cat对象,甚至Animal类对象以及Animal 类其他子类对象,并且在方法中调用eat方法 
// 形参多态: 参数的类型是父类类型,那么就可以接收该父类类型的对象以及该父类类型的 所有子类对象 
// 实参赋值给形参的时候构成了多态 
	public static void method(Animal anl){ 
		anl.eat(); 
	}
	// 需求:定义一个方法,可以接收Dog对象,并且在方法中调用eat方法 
	/*public static void method1(Dog dog){ dog.eat(); }*/ 
	// 需求:定义一个方法,可以接收Cat对象,并且在方法中调用eat方法 
	/*public static void method2(Cat cat){ cat.eat(); }*/ // ... 
}

3.3、返回值多态 -----> 常用

结论: 返回值类型为父类类型,那么就可以返回该父类类型的对象,或者该父类类型的子类对象
对象

class Animal { 
	public void eat() { 
		System.out.println("吃东西..."); 
	}
}
class Dog extends Animal { 
	public void eat() { 
		System.out.println("狗吃骨头..."); 
	} 
}
class Cat extends Animal { 
	public void eat() { 
		System.out.println("猫吃鱼..."); 
	} 
}
public class Test { 
	public static void main(String[] args) { 
		// 接收返回值的时候其实就是多态: 
		Animal anl1 = new Dog(); 
		Animal anl1 = method1("Dog"); 
		anl1.eat();// 狗吃骨头... 
		System.out.println("====="); 
		// 接收返回值的时候其实就是多态: 
		Animal anl2 = new Cat(); 
		Animal anl2 = method1("Cat"); 
		anl2.eat();// 猫吃鱼... 
	}
// 定义一个方法,可以返回Dog对象,也可以返回Cat对象,也可以返回Animal对象,或者Animal 类的其他子类对象 // 返回值多态: 返回值类型为父类类型,那么就可以返回该父类类型的对象,或者该父类类型的子 类对象
	public static Animal method1(String classType) { 
		//return new Dog(); 
		//return new Cat(); 
		//return new Animal(); 
		if ("Dog".equals(classType)) { 
			return new Dog(); 
		} else if ("Cat".equals(classType)) { 
			return new Cat(); 
		} else if ("Animal".equals(classType)) { 
			return new Animal(); 
		} else { return null; } 
	} 
}

4、多态的好处和弊端

4.1、好处:

可以将方法的参数定义为父类引用,使程序编写的更简单,提高程序的灵活性,扩展性 案例参考多态的应用场景;

4.2、弊端:

无法直接访问子类独有的成员变量和成员方法(因为多态时成员访问特点编译都是看左边(父 类))

4.3、案例:

class Animal { 
	public void eat() { 
		System.out.println("吃东西..."); 
	} 
}
class Dog extends Animal { 
	// 独有的成员变量 
	int num = 10; 
	@Override 
	public void eat() { 
		System.out.println("狗吃骨头..."); 
	}
	// 独有的成员方法 
	public void lookHome() { 
		System.out.println("狗正在看家..."); 
	} 
}
public class Test { 
	public static void main(String[] args) { 
		// 多态的弊端: 无法访问子类独有的成员变量和成员方法 
		// 变量多态 
		Animal anl1 = new Dog(); 
		// System.out.println(anl1.num);// 编译报错,因为编译看左边,父类没有 num成员变量
		// anl1.lookHome();// 编译报错,因为编译看左边,父类没有lookHome成员方法 
		// 返回值多态 
		Animal anl2 = method1("Dog"); 
		// System.out.println(anl2.num);// 编译报错,因为编译看左边,父类没有 num成员变量
		// anl2.lookHome();// 编译报错,因为编译看左边,父类没有lookHome成员方法 }
		// 形参多态 
		public static void method(Animal anl) { 
			anl.eat(); 
			// anl.lookHome();// 编译报错,因为编译看左边,父类没有lookHome成员方法 
		}
		// 返回值多态 
		public static Animal method1(String classType) { 
			//return new Dog(); 
			//return new Cat(); 
			//return new Animal(); 
			if ("Dog".equals(classType)) { 
				return new Dog(); 
			} else if ("Animal".equals(classType)) { 
				return new Animal(); 
			} else {
				return null; 
			} 
		} 
}

5、引用类型转换

5.1、为什么要转型

1、为了实现多态
2、为了解决多态的弊端

5.2、如何转型:

1、向上转型: 父类类型 变量名 = new 子类名(实参); 向下转型: 子类类型 变量名 = (子类类型) 父类类型的变量;
2、注意:
父类类型的变量指向的对象一定是左边子类类型的对象,否则会报类型转换异常 ClassCastException

5.3、避免转型异常—>转型判断

1、instanceof关键字
2、格式: 变量名 instanceof 数据类型
3、执行:
如果变量指向的对象的数据类型是属于后面的数据类型,就返回true,否则返回false

5.4、案例:

class Animal { 
	public void eat() { 
		System.out.println("吃东西..."); 
	} 
}
class Dog extends Animal { 
	// 独有的成员变量 
	int num = 10; 
	@Override 
	public void eat() { 
		System.out.println("狗吃骨头..."); 
	}
	// 独有的成员方法 
	public void lookHome() { 
		System.out.println("狗正在看家..."); 
	} 
}
class Cat extends Animal { 
	@Override 
	public void eat() { 
		System.out.println("猫吃鱼..."); 
	}
}
public class Test1 { 
public static void main(String[] args) { 
/* 
为什么转型 
	1.为了实现多态 
	2.为了解决多态的弊端(无法访问子类独有的成员变量和成员方法) 
引用类型转换分类 
	向上转型:
		子类类型向父类类型转换的过程,称为向上转型。这个过程是默认的。 
	格式:
		父类类型 变量名 = new 子类类型() 或 子类对象引用; 
		Dog d = new Dog(); 
		Animal anl = new Dog(); 
		Animal anl = d; 
	向下转型:
		父类类型向子类类型转换的过程,称为向下转型,这个过程需要强制执 行。 
	格式:
		子类类型 变量名 = (子类类型) 父类类型变量; 
	要求: 
		父类类型的变量必须指向的是前面子类类型的对象 
	类型转换判断: 
		使用instanceof关键字 
	格式: 
		变量名 instanceof 数据类型 
	执行: 
		如果变量指向的对象是属于后面的数据类型,那就返回true 
		如果变量指向的对象不属于后面的数据类型,那就返回false */
// 向上转型: 父类类型的引用指向子类类型的对象 
	Animal anl1 = new Dog(); 
	anl1.eat(); 
	// System.out.println(anl1.num);// 编译报错 
	// anl1.lookHome();// 编译报错 
	//Dog d = new Dog(); 
	//Animal anl2 = d; 
	System.out.println("======="); 
	// 改变anl1指向的对象 
	anl1 = new Cat(); 
// 向下转型: 子类类型向父类类型转换的过程 
	if (anl1 instanceof Dog){ 
		Dog dog = (Dog) anl1;
		System.out.println(dog.num); 
		dog.lookHome(); 
		} 
	} 
}

四、内部类

1、4.1 内部类的概述

1、概述: 将一个类定义在另一个类的里面,里面的那个类就叫做内部类,外面的那个类就叫做外部类
2、特点:
内部类是一个独立的类,在编译后,有自己独立的class文件,前面冠以:外部类名+$+内部类 类名
3、分类:
成员内部类
匿名内部类
局部内部类(自己了解)

4.2 成员内部类

1、概述: 定义在类的成员位置(类中方法外)的类就叫做成员内部类
2、格式:
class 外部类名{ class 内部类名{ } }
3、成员访问特点:
成员内部类中的成员变量和成员方法在其他类中访问,需要创建成员内部类对象
4、格式: 外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

案例:

public class Body { 
	public class Heart{ 
		// 成员变量 
		int numN = 20; 
		// 成员方法 
		public void methodN1(){ 
			System.out.println("成员内部类的methodN1方法..."); 
		} 
	} 
}
public class Test { 
	public static void main(String[] args) { 
		// 创建Heart对象 
		Body.Heart bh = new Body().new Heart(); 
		System.out.println(bh.numN); bh.methodN1();
	 } 
 }

注意事项: 在成员内部类中,可以直接访问外部类的一切成员,包括外部类的私有成员
在外部类中,需要直接访问内部类的成员,需要创建内部类对象来访问

public class Body { 
	int numW = 10; 
	public void methodW1(){ 
		System.out.println("外部类的methodW1方法..."); 
	}
		// - 在外部类中,需要直接访问内部类的成员,需要创建内部类对象来访问 
	public void methodW2(){ 
		System.out.println("外部类的methodW2方法..."); 
		// 创建内部类对象 
		Heart heart = new Heart(); 
		System.out.println(heart.numN); 
		heart.methodN1(); 
	}
	public class Heart{ 
		// 成员变量 int numN = 20; 
		// 成员方法 
		public void methodN1(){ 
			System.out.println("成员内部类的methodN1方法..."); 
		}
		// - 在成员内部类中,可以直接访问外部类的一切成员,包括外部类的私有成员 
		public void methodN2(){ 
			System.out.println(numW); methodW1(); 
		} 
	} 
}
public class Test { 
public static void main(String[] args) { 
	// 创建Heart对象 
		Body.Heart bh = new Body().new Heart(); 
		System.out.println(bh.numN); 
		bh.methodN1(); 
		bh.methodN2(); 
		System.out.println("======"); 
		new Body().methodW2(); 
	} 
}

4.3 匿名内部类(重点)

1、概述
本质其实就是一个类的子类对象
本质其实就是一个接口的实现类对象
2、格式
new 类名(){ 必须重写所有抽象方法 };
new 接口名(){ 必须重写所有抽象方法 };
3、使用场景
如果想得到一个抽象类的子类对象,那么就可以直接给该类的匿名内部类
如果想得到一个接口的实现类对象,那么就可以直接给该接口的匿名内部类

案例1:

abstract class Animal{ 
	public abstract void eat(); 
}
public class Test { 
	public static void main(String[] args) { 
		// 需求:调用Animal类的eat方法 
		/* 
			以前:
				1.创建一个子类继承Animal类,在子类中重写eat方法 
				2.创建子类对象
				3.使用子类对象调用eat方法 
			现在:
				直接创建Animal类的匿名内部类,然后使用该匿名内部类调用eat方法即可 
		*/ 
		// 父类的引用指向子类的对象 
		Animal anl1 = new Animal() { 
			@Override public void eat() { 
				System.out.println("匿名内部类的eat..."); 
			} 
		};
		anl1.eat(); 
	} 
}

案例2:

interface IA{ 
	void show(); 
}
public class Test { 
	public static void main(String[] args) { 
		// 需求:得到IA接口的实现类对象调用show方法 
		/* 
		以前:
			1.创建一个实现类实现IA接口,重写show方法 
			2.创建实现类对象 
			3.使用实现类对象调用show方法 
		现在:
			直接创建IA接口的匿名内部类调用show方法
		 */
		  IA a = new IA() { 
			  @Override public void show() {
			  	 System.out.println("匿名内部类的show"); 
			   } 
			   };
			 	  a.show();
			   	 System.out.println("=====");
			     new IA() { 
				     @Override public void show() {
				      System.out.println("匿名内部类的show"); 
			      } 
		      }.show(); 
	      }
  }

java后续基础内容正在快马加鞭更新中,内容若有误,欢迎各位码友提出建设性意见。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值