学习java—第十四天学习笔记

526 阅读8分钟

2019.7.30 NIIT第十四天

/半个月过去了,冲冲冲!/

/月亮与六便士:我用尽了一身过着平凡的生活/

一、抽象类与抽象方法

抽象类的概念:抽象类用来描述一种类型应该具备的基本特征与功能,具体如何去完成这些行为由子类通过方法重写来完成

抽象方法:指只有功能声明,没有功能主体实现的方法

关键字:abstract

Tips:抽象方法必须存放在抽象类中

抽象类的作用:

规范子类->子类如果是普通类,继承抽象父类后必须实现抽象方法

子类重写方法的访问权限必须大于等于父类,实现抽象方法也一样

特性:抽象类中可以没有抽象方法,可以有普通方法

二、抽象类构造方法存在的意义

子类构造方法中通过super语句调用抽象父类的构造方法,为抽象父类中的成员变量赋值初始化;

而赋好值的成员变量可以被子类的对象使用。

面试:抽象类不允许直接创建对象通过构造方法给父类的属性进行赋值

三、抽象类的特点及常见困惑

A:抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中。

B:抽象类不可以直接创建对象,原因:调用抽象方法没有意义。

C:只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类。

四、抽象类的疑虑

A:抽象类一定是个父类,因为抽象类是不断抽取共性需求而来的。 B:抽象类中是可以不定义抽象方法的,此时仅仅是不让该类创建对象,用于某些特殊的设计需要。 C:设计时由具体类抽取出抽象类,而开发阶段应该先定义抽象父类,再根据不同需求由父类定义子类。

五、接口概念

接口是一种特殊的抽象了:里面所有的方法都是抽象类

  • 接口是功能的集合,同样可看作是一种数据类型,是比抽象类更为抽象的”类”。
  • 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。
  • 请记住:一切事物均有功能,即一切事物均有接口。

六、接口的实现

  • interface 定义接口的关键字
  • implments 实现接口的关键字

隔离与父类不同的功能,规范作用,子类实现接口中所有的抽象类

七、接口的注意事项

A:类单继承类,接口多继承接口,接口之间可以多继承(extends)

B:类可以在继承一个类的同时,实现多个接口

C:接口与父类的功能可以重复,均代表要具备某种功能,并不冲突

D:面试->extends必须写在implments之前,否则编译不通过

E:接口中所有的方法都是抽象方法

F:接口中所有的方法都是被public,abstract修饰的

G:接口中的属性需要在接口中初始化,且被认为是常量

public final String name="Tom";
public abstract void method();
	class A {
		public void method() {
		}
	}
	
	interface B {
		public abstract void method();
	}
	class C extends A implements B {
	//如果不重写method()方法,使用的是A中的method()方法
	//如果重写method()方法将同时重写A和接口B中的method()方法
	}

子类在实现父类和接口方法的时候,如果该方法只有返回类型不同时,无法进行实现或重写,因为系统无法区分重写/实现了那个方法,且一个类中无法出现两个只有返回值类型不同的同名方法----->应对方法:改名字.....

八、区分接口中方法与父类抽象方法的默认修饰区别

  • 方法上:

接口中的所有方法都默认被public,abstract修饰

父类中的抽象方法只被默认权限修饰

  • 属性上:

接口的属性都是常量,不可在外修改

抽象父类中的属性可以修改,根据权限,调用get/set方法

九、接口与抽象类概念的辨析

A:当"我是你的一种时",子类继承父类,即代表了类与类之间的关系,该体系的类都应该具备父类的成员。

例如:厨师,经理,服务员 都属于员工 的一种,都应该继承员工

B:当"我应该像你一样具备这些功能时",类实现接口,即代表类与功能的关系,将功能的声明与实现分离。并不是该体系内所有类都需要的额外功能。

例如:只有经理 和司机

具备开车的技能,需要把开车的技能单独定义在接口中,让经理和司机去实现

十、接口与抽象类使用辨析

A:

  • 类继承类extends,只能单继承
  • 接口继承接口extends,可以多继承
  • 类实现接口implements,可以多实现
  • 接口不可以继承类

B:

  • 抽象类中可以有非抽象方法
  • 接口中全部为抽象方法

C:

  • 抽象类具有成员变量
  • 接口没有普通的成员变量

D:

  • 抽象类中的成员无固定修饰符
  • 接口中的成员有固定修饰符

十一、多态

子类能够代替父类使用

子类由于继承了父类的方法,在使用的时候子类可以调用父类方法,从而代替父类

目的:简化代码(子类代替父类的部分代码)

普通类定义多态的格式

	父类 变量名 = new 子类();
	如:	class Fu {}
		class Zi extends Fu {}
		//类的多态使用
	Fu f = new Zi();

抽象类多态的定义

	抽象类 变量名 = new 抽象类子类();
	如:	abstract class Fu {
	         public abstract void method();
		     }
	class Zi extends Fu {
	public void method(){
			System.out.println(“重写父类抽象方法”);
		}
	}
	//类的多态使用
	Fu fu= new Zi();

声明为父类,利用子类方法创建对象

在以对象为参数的方法中利用这种方法可以减少方法的重载,降低代码量

父类可以为抽象类或者是接口

声明为接口,实际创建的子类

/理解:在Manager类中方法调用父类对象作为参数进行传递时,可以传入子类对象代替父类,降低方法重载的代码量 (一个类中叫重载,两个类中叫重写)/

十二、多态的使用场景

A: 使用多态为成员变量赋值,局部变量赋值(一般不常用.....那你还讲那么认真,你不会提前讲啊)

	class Father{
		
	}
	class Son extends Father{
	   	Father f=new Son();//使用多态形式为成员变量f赋值
	
		public void method(){
		   Father f2=new Son();//使用多态的形式为局部变量f2赋值
	   	}
	}

B: 方法传参使用多态形式(最常用最能体现出多态优点的应用)(就是我上面理解的那种形式)

	class Father{
		
	}
	class Son extends Father{
		
	}
	class Demo{
		public static void main(String[] args) {
			Son s=new Son();
			method(s);
		}
		public static void method(Father f){//f接收父类对象或者子类对象
			
		}
	}

1、在调用类的方法参数中使用父类

2、在测试类中使用子类代替父类进行传参

C: 方法返回返回值使用多态形式

	class Father{
		
	}
	class Son extends Father{
		
	}
	class Demo{
		public static void main(String[] args) {
			Son s=new Son();
			Father f=method();
		}
		public static Father method(){ 
	        	Son s = new Son();
			//由于返回值类型为Father,所以既可以返回父类对象又可以返回子类对象
			return s; 
		}
	}

当我想用子类代替父类去使用的时候,父类就可以定义为接口

十三、多态的转型

//大小指的是图示包含关系的大小

一般把子类(大)转成父类(小)

把父类不能直接转换成子类,当把父类强制转换成子类时编译不会出错,运行时可能出错 对类在创建的时候:

声明类型 对象名=new 构造方法;
声明类型一般范围小于等于构造方法

总结: 做类型转化一般从子类转换成父类可以直接转换,如果要调用子类的方法,把父类强转成子类对象就可以使用从父类转成子类,可以强转。但是可能会出现错误一般情况我们使用多动态都是从子类转换成父类

十四、instanceof

通过instanceof关键字来判断某个对象是否属于某种数据类型

声明类型 对象名=new 构造方法;

使用什么构造方法,对象就是什么对象,只是声明可能不对应

对象是否使用后者的构造器,决定该对象是否属于后者类的对象

如果结果都为true,则说明该对象属于后者类,那么就可以实现子类到父类的转换

使用格式:
	boolean  b  = 对象  instanceof  数据类型;
		如
	// 前提条件,学生类已经继承了人类
	Person p1 = new Student(); 
	boolean flag = p1 instanceof Student; //true
	boolean flag2 = p2 instanceof Teacher; //false

/父类转子类,强转有可能会出错!子类转父类,可以直接转/