Java基础之接口和多态知识点总结


接口
当抽象类的方法都是抽象的时候,这时可以把该类定义成接口的形式。你可以先期将接口理解为特殊的抽象类。
Eg.接口特点:
   1,接口的方法都是抽象的。
   2,接口不可以被实例化。
   3,只有子类实现了接口中的所有抽象方法后,该子类才可以实例化,否则该类还是一个抽象类。
格式特点当定义接口时,接口中的常见的成员有两种:
   1,全局常量。
   2,抽象方法。
而且接口中的成员都有固定的修饰符:
    全局常量:public static final 
    成员方法:public abstract
这修饰即使不写,系统也会自动加上。
建立一定书写,因为可以提高程序的阅读性。你会发现,接口中定义的成员都有一个共同的特点:都是public权限的。
继承和实现的一点小区别:
类与类之间称为继承:因为该类无论是抽象的还是非抽象的,它内部可以定义非抽象方法,这个方法可以直接被子类使用,所以子类继承就可以应用了。类与接口是实现关系:因为接口中的方法全都是抽象的,必须由子类实现完才可以实例化。所以就用了更确切的关键字:implements来表示
例子1.接口的引例实例演示。
package cn.itheima.day16;
/**
 * 先前可以把接口理解为特殊的抽象类。
 * 例如下面的代码:
 * interface Inter{
 *    public static final int num = 4;
 *    public abstract void show();
 * }
 * 接口-------->抽象类
 * abstract class AbsDemo{
 *    abstract void show();
 *    abstract void method();
 * }
 */
//定义一个接口
interface Inter{
	public static final int num = 6;
    public abstract void show();
    public abstract void method();
}
/**
 * 如果要使用接口中的方法,必须定义一个类实现接口中的所有的抽象
 * 方法后,该子类才可以建立对象,并调用这些方法。
 * @author wl-pc
*/
//实现接口
class InterImpl implements Inter{
	@Override
	public void show() {
		System.out.println("show run");
	}
	@Override
	public void method() {
	    System.out.println("method run");
	}
}
public class InterfaceDemo {
	public static void main(String[] args) {
		InterImpl i = new InterImpl();
		i.show();
		i.method();
		System.out.println(Inter.num);
		System.out.println(InterImpl.num);
		System.out.println(i.num);
	}
}
类只能单继承,而接口可以被多实现。
java将多继承机制进行改良,通过多实现接口的形式来体现。
为什么不支持多继承呢?
因为当多个父类中定义了相同方法,而方法内容不同是,子类对象在调用该方法时,不明确要运行哪一个,有安全隐患,也就是不确定性。而接口进行多实现就没有这个问题了,因为接口中的方法都没有主体。接口的另一个好处:一个类在继承另一个类的同时可以实现多个接口.接口的出现就避免了单继承的局限性。父类中定义的该对象的基本功能,而接口中定义的是该对象的扩展功能。

例子2.接口的多实现的实例演示。

package cn.itheima.day16;
class Demo{
	public void function(){
		System.out.println("function run");
	}
}
interface Inter1{
	void show();
}
interface Inter2{
	void show();
}
//多实现接口的演示
class DemoA implements Inter1,Inter2{  //接口可以多实现
	public void show(){
		System.out.println("多实现接口的DemoA run");
	}
	public void method(){
		System.out.println("method run");
	}
}
//继承类并实现接口的演示
class Test extends Demo implements Inter1,Inter2{
	@Override
	public void show() {
		System.out.println("单继承和多实现接口的show run");
	}
}
public class InterfaceDemo2 {
	public static void main(String[] args) {
		DemoA d = new DemoA();
		d.show();
		d.method();
		Test test = new Test();
		test.show();
         t.function();
	}
}
抽象类和接口的区别:
    1.抽象类只能被单继承。
      接口可以被多实现。
    2.抽象类中可以定义非抽象方法,直接被子类使用。
      接口中只有抽象方法,必须被子类实现后才可以被使用。
    3.抽象类中定义体系中的基本共性功能。
      接口中通常定义体系中对象的扩展功能。
    4.接口的出现避免了单继承的局限性。
    5.抽象类被继承,是 is a 关系: xx1是xx2中的一种。
      接口可以被实现,是 like a关系:xx1像xx2 中的一种。
例子3:抽象类和接口的整合实例演示。
package cn.itheima.day16;
/**
 * 学员的例子
 * 抽烟的学员
 * 
 * 老师
 * 抽烟的老师
 * @author wl-pc
*/
/*发现抽烟的功能并不是体系中应该具备的基本功能。而是具体子类所具备的特有扩展
 * 功能。将这个功能抽取到一个接口中,这个是对对象的功能进行扩展*/
interface Smoking{
	public abstract void smoke();
}
//学员的抽象类
abstract class XueYuan{
	abstract void study();
}
class SmokeXueYuan extends XueYuan implements Smoking{
	@Override
	void study() {
		System.out.println("study");
	}
	@Override
	public void smoke() {
		System.out.println("Xueyua Smoke");
	}
}
//老师的抽象类
abstract class Teacher{
	abstract void teacher();
}
class SmokeTeacher extends Teacher implements Smoking{
	@Override
	void teacher() {
		System.out.println("teacher");
	}
	@Override
	public void smoke() {
		System.out.println("teacher smoke");
	}
}
public class InterfaceDemo3 {
	public static void main(String[] args) {
		SmokeXueYuan  xueYuan = new SmokeXueYuan();
		xueYuan.smoke();
		xueYuan.study();
		SmokeTeacher teacher = new SmokeTeacher();
		teacher.teacher();
		teacher.smoke();
	}
}
/* 改变问题领域(如下):
 * 分析烟民这个领域。 
 * abstract class YanMin {
 *      abstract void smoke(); 
 *  }
 * 对于烟民而言,吸烟是主要功能,而学习是添加的功能。
 * interface Study { 
 *      void study(); 
 * }
 * 烟民不一定都具有学习的功能,所以将学习功能定义为借口
 * class StudentYanMin extends YanMin implements Study {
 *     void smoke() {
 *          System.out.println("Student smoke"); 
 *     } 
 *     public void study(){} 
 * }
 */
类与类之间是继承关系。
类与接口之间是实现关系。
接口与接口之间继承关系,通过接口可以多继承。
Java支持多继承,在类上,Java的多继承是不允许的,因为存在着不确定性。但是,在接口上可以存在多继承的。
例子4:接口的多实现的实例演示。
package cn.itheima.day16;
interface A{
	void a();
}
interface C{
	void c();
}
interface B extends A,C{
	void b();
}
class D implements B{
	@Override
	public void a() {
		System.out.println("a");
	}
	@Override
	public void c() {
		System.out.println("c");
	}
	@Override
	public void b() {
		System.out.println("b");
	}
}
/*class AA{}
class BB{}
//这种写法是错误的,因为类只支持单继承,不支持多继承
class CC extends AA,BB{
}*/
public class InterfaceDemo4 {
	public static void main(String[] args) {
		D d = new D();
		d.a();
		d.c();
		d.b();
	}
}
猫,狗:这些事物都称为动物。
动物这种类型:有多种体现的形态。
   一个具体的动物,具备多种体现类型。(猫:称为猫或动物)
    猫这个具体对象,它既可以称之为猫,也可以称之为动物。
    class 动物{
    }
    class 猫 extends 动物{
    }
    猫 x = new 猫();
    动物 y = new 猫();
    class 狗 extends 动物{
    }
    狗 x = new 狗();
    动物 y = new 狗();
    多态        1,在程序中的体现:父类引用或者接口引用指向了自己的子类对象。
        2,好处:提高了代码的扩展性,后期的可维护性
        3,前提            1)类与类之间必须有继承关系或者实现关系。
            2)通常都需要进行覆盖。
        4,弊端           进行多态应用时,前期并不知道后期会有多少个子类出现,但是可以使用父类的引用来调用父类的方法。而后期哪个子类对象出现就执行哪个子类的具体方法实现。这就是程序的扩展性。
      但是,前期调用的时候,只能调用父类中的方法,而不能调用具体子类的特有方法。因为前期还不知道具体的子类是谁。
多态的思想    以前:定义对象,并指挥对象做事情(调用对象方法)当对象多了以后,指挥动作就会变的很麻烦。这时重新思考这个问题。找到这些对象的共性类型。直接指挥这个共性类型做事情即可。这样凡是属于这个类型的个体都会执行。
    比如:建立猫对象,调用猫的eat方法。建立狗对象调用eat方法。很麻烦。
    找到猫和狗的共性类型:动物。只要指挥动物的eat方法。即可。这样猫和狗都会进行eat动作。

例子5:多态的演示程序。

package cn.itheima.day16;
abstract class Animal{
	abstract void eat();
}
class EatSomething{
	void startEat(Animal a){
		a.eat();
	}
}
class Cat extends Animal{
	void eat(){
		System.out.println("鱼");
	}
	void catchMouse(){
		System.out.println("做老鼠");
	}
}
class Dog extends Animal{
	@Override
	void eat() {
		System.out.println("骨头");
	}
    void looHome(){
    	System.out.println("看家");
    }	
}
public class DuoTaiDemo1 {
	public static void main(String[] args) {
		EatSomething es = new EatSomething();
		es.startEat(new Cat());
		es.startEat(new Dog());
	}
}

在转型过程中,其实都是子类对象在做着变化。当你想使用子类的特有功能时,需要将父类型转成子类型才可以使用。
注意:必须保证,这个父类型指向的是该子类型的对象.
例子6:多态中的对象的向上转型和向下转型的实例演示。

package cn.itheima.day16;
abstract class Animal1{
	abstract void eat();
}
class EatSomething1{
	void startEat(Animal1 a){
		a.eat();
	}
}
class Cat1 extends Animal1{
	void eat(){
		System.out.println("鱼");
	}
	void catchMouse(){
		System.out.println("做老鼠");
	}
}
class Dog1 extends Animal1{
	@Override
	void eat() {
		System.out.println("骨头");
	}
    void looHome(){
    	System.out.println("看家");
    }	
}
public class DuoTaiDemo2 {
	public static void main(String[] args) {
		Animal1 a = new Cat1(); //父类引用指向子类对象,子类对象提升为了父类型,向上转型。自动类型提升。
		a.eat();
		//c.catchMouse(); //编译错误
		
		//注意:在转型过程中,至始至终都是子类对象在做着改变。
		//当你想使用子类的特有功能时,需要将父类型转成子类型才可以使用。
		//注意:必须保证,这个父类型指向的该子类型的对象。
		//想要使用猫的做老鼠的功能,强制类型转换,向下转型。
		Cat1 c = (Cat1)a;
		c.eat();
		c.catchMouse();	     
	}
}

可以对传入的对象进行类型的判断。通过一个关键字来完成 instanceof : 对象instanceof 类型  
用于判断该对象是否所属于该类型。
例子7:判断对象类型是否属于指定的类型。
package cn.itheima.day16;
import java.lang.reflect.Method;

abstract class Animal2{
	abstract void eat();
}
class EatSomething2{
	void startEat(Animal2 a){
		a.eat();
	}
}
class Cat2 extends Animal2{
	void eat(){
		System.out.println("鱼");
	}
	void catchMouse(){
		System.out.println("做老鼠");
	}
}
class Dog2 extends Animal2{
	@Override
	void eat() {
		System.out.println("骨头");
	}
    void looHome(){
    	System.out.println("看家");
    }	
}
public class DuoTaiDemo3 {
	public static void main(String[] args) {
	    Method(new Dog2());
	}
	private static void Method(Animal2 a) {
		//可以对传入的对象进行类型的判断。
		//通过一个关键字来完成 instanceof : 对象 instanceof 类型  用于判断该对象是否所属于该类型。
		if(a instanceof Cat2){
			Cat2 c= (Cat2)a;
			c.eat();
			c.catchMouse();
		}else if(a instanceof Dog2){
			Dog2 d = new Dog2();
			d.eat();
			d.looHome();
		}else {
			a.eat();
		}
	}
}
接口的基本思想:
  举例说明:主板的例子。
  接口的三个特性:
     1.接口就是对外暴露的规则。
     2.接口是功能的扩展。
     3.接口的出现降低了耦合性(紧密联系程度降低),耦合性的降低就实现了模块化的开发,叫做开发前定义好规则,你在实现规则,我在使用规则,至于怎么实现的和我没关系。我只要知道这个规则即可。
  面试回答:电脑的机箱
                  电源插孔的例子
                 笔记本的例子
                 主板的例子
例子8:主板运行和PCI结合的实例演示。
package cn.itheima.day16;
/**
* 需求:主板运行。为了提高主板的功能扩展。因为日后有可能会出现一些新的功能,比如音频,网络等等。
* 以后会出现什么样的功能,是不确定的。但是前期在设计的时候,可以对外提供一个规则。只要后期的
* 功能设备符合这个主板对外提供的规则即可被主板使用。就在主板上定义了PCI插槽。 这个插槽就是一个接口。
* 这个示例作为一个重点看一下
 * @author wl-pc
 */
/**
 * 接口的基本思想:
 * 举例说明:主板的例子。
 * 接口的三个特性:
 *    1.接口就是对外暴露的规则。
 *    2.接口是功能的扩展。
 *    3.接口的出现降低了耦合性(紧密联系程度降低),耦合性的降低就实现了模块化的开发, 叫做开发前定义好规则,你在实现规则,我在使用规则,至于怎么实现的和我没关系。我只要知道这个规则即可。
 * 面试回答:电脑的机箱
 *          电源插孔的例子
 *          笔记本的例子
 *          主板的例子
 */
interface PCI{
	public void open();
	public void close();
}
class MainBoard{
	public void run(){
		System.out.println("mainboard run");
	}
	/**
	 * 主板还有一个功能,就是使用PCI插槽上的具体设备。
	 * 只要定义PCI 接口的引用,用于接收符合该接口的设备即可。
	 */
	public void usePCI(PCI p){  //p就是一个接口类型的应用,接口类型的引用需要指向其子类的对象。
		if(p!=null){
			p.open();
			p.close();
		}
	}
}
//定义网卡实现PCI接口
class NetCard implements PCI{
	@Override
	public void open() {
		System.out.println("netcard open");
	}
	@Override
	public void close() {
		System.out.println("netcard close");
	}
}
//定义声卡实现PCI接口
class SoundCard implements PCI{ //like a关系 :网卡很像一个PCI
	@Override
	public void open() {
		System.out.println("SoundCard open");
	}
	@Override
	public void close() {
		System.out.println("SoundCard close");
	}
}
public class PCIDemo {
	public static void main(String[] args) {
		MainBoard mb = new MainBoard();
		mb.run();
		mb.usePCI(new NetCard());
		mb.usePCI(new SoundCard());
	}
}
例子9:数据库使用接口的实例演示。
interface SQLTool{
	add();
	delete();
}
class MySqlTool implements SQLTool{
	add(){
		1,连接mysql数据库。
		2,添加数据。
		3,关闭数据库。
	}
	delete(){
		1,连接mysql数据库。
		2,删除数据。
		3,关闭数据库。
	}
}
class OracleTool implements SQLTool{
	add(){
		1,连接Oracle数据库。
		2,添加数据。
		3,关闭数据库。
	}
	delete(){
		1,连接Oracle数据库。
		2,删除数据。
		3,关闭数据库。
	}
}
//定义一个工具类,返回指定的对象。
class Tool{ //静态工厂设计模式。
	public static SQLTool getInstance(String name){
		if(name.equals("mysql"))
			return new MySqlTool();
		if(name.equals("oracle))
			return new OracleTool();
	}
}
class SQLDemo{
	public static void main(String[] args){
	     SQLTool t = Tool. getInstance(“mysql”);
          t.add();
          t.delete();
			
          SQLTool t2 = Tool. getInstance(“oracle”);
          t2.add();
          t2.delete();
	}
}
多态中的细节。
在多态中:
    成员变量       编译时期:看的引用型变量所属的类中是否有所调用的变量.
       运行时期:也是看引用型变量所属的类是否有调用的变量。
       简单一句话:成员变量,无论编译还是运行都看引用型变量所属的类。
       更简单的话:成员变量,编译和运行都看等号 的左边。
    成员函数       编译时期:看的引用型变量所属的类中是否有调用的方法。
       运行时期:看的对象所属的类中是否有调用的方法,
       如果父子出现同名方法,会运行子类中的方法。因为方法有覆盖特性。
       简单说:对于成员函数,编译看左边,运行看右边。
其实非静态函数,在内存有一个动态绑定机制。其实就是f指向了具体的子类对象。编译看到的f所属的Fu类中是否有这个方法。运行的时候f就绑定到了一个具体的子类对象上,子类对象运行时会覆盖父类中的相同方法,而运行子类的内容。
    静态函数       编译时期:看的是引用型变量所属的类中是否有调用的方法。
       运行时期:也是看的是引用型变量所属的类中是否有调用的方法。
       简单说: 对于静态函数,编译看左边,运行也看左边.
静态函数存放于每一个所属类的静态区中,它是被静态绑定,就是类一加载,就已经有固定所属的调用就是那个类名。
整体总结    成员变量和静态成员:编译和运行都看左边。
    只有非静态的成员函数:编译看左边,运行看右边。
当定义功能时,该功能中有一部分功能是确定,一部分功能是不确定的。
这时将不确定的部分通过一个函数暴露出去,延迟到子类去完成。这时我们发现解决这类功能部分明确部分不明确需求,用这个思想就可以很高效。这个思想就成了一个解决该类问题就有效的方案。起个名字就叫做:模版方法设计模式。
例子10:模版方法设计模式的实例演示。
package cn.itheima.day16;
import org.omg.IOP.Codec;
/*
计算一个程序运行的时间。
思路:
在该程序运行之前记录一个时间。
运行完在记录一个时间,相减即可.
如何获取时间呢?
*/
/*
为了提高该功能的复用性,将该功能封装到对象中。只要以后使用时找到该对象即可。
当定义功能时,该功能中有一部分功能是确定,一部分功能是不确定的。
这是将不确定的部分通过一个函数暴露出去,延迟到子类去完成。
这是我们发现解决这类功能部分明确部分不明确需求,用这个思想就可以很高效。
这个思想就成了一个解决该类问题就有效的方案。起个名字就叫做:模版方法设计模式。
*/
abstract class GetTime{
	public final void getTime(){
		long  start = System.currentTimeMillis();
		code();
		long  end = System.currentTimeMillis();
		System.out.println("毫秒="+(end-start));
	}
	public abstract void code();
}
class Sub extends GetTime{
	public void code(){
		for(int x=0; x<1000; x++){
			System.out.println("y");
		}
	}
}
public class TemplateDemo {
	public static void main(String[] args) {
		Sub sub = new Sub();
		sub.getTime();
	}
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中继承、接口多态是面向对象编程的三大核心特性,以下是它们的实验总结: 1. 继承:继承是一种重用代码的方式,它允许我们定义一个新的,该继承了现有的属性和方法。在Java中,继承是通过关键字"extends"来实现的。 在实验过程中,我们可以通过定义一个父,然后在子中使用"extends"关键字继承父的属性和方法。例如: ```java class Animal { public void eat() { System.out.println("Animal is eating"); } } class Dog extends Animal { public void bark() { System.out.println("Dog is barking"); } } ``` 在上面的例子中,Dog继承了Animal的eat()方法。我们可以实例化Dog并调用eat()方法,因为Dog继承了Animal的行为。 2. 接口接口是一种定义行为的方式,它定义了应该如何相互协作。在Java中,接口是通过关键字"interface"来定义的。 在实验过程中,我们可以通过定义一个接口来定义的行为,然后让实现该接口。例如: ```java interface Animal { public void eat(); } class Dog implements Animal { public void eat() { System.out.println("Dog is eating"); } } ``` 在上面的例子中,Animal接口定义了eat()方法,然后Dog实现了该接口并实现了eat()方法。 3. 多态多态是一种对象的行为表现方式,它允许我们使用一个父的引用来引用一个子的对象。在Java中,多态是通过继承和接口来实现的。 在实验过程中,我们可以定义一个父的引用,并使用该引用来引用一个子的对象。例如: ```java class Animal { public void eat() { System.out.println("Animal is eating"); } } class Dog extends Animal { public void eat() { System.out.println("Dog is eating"); } } public class Main { public static void main(String[] args) { Animal a = new Animal(); Animal b = new Dog(); a.eat(); // 输出 "Animal is eating" b.eat(); // 输出 "Dog is eating" } } ``` 在上面的例子中,我们定义了一个Animal和一个Dog,然后在main()方法中定义了一个Animal型的引用a和一个Animal型的引用b,并使用它们来引用一个Animal对象和一个Dog对象。由于Dog继承了Animal的eat()方法,并且重写了该方法,因此在调用b.eat()方法时,输出的是"Dog is eating"。这就是多态的表现方式。 总的来说,继承、接口多态Java面向对象编程的三大核心特性,它们可以帮助我们更好地组织代码、提高代码的可重用性和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值