JAVA基础知识—-面向对象之继承(抽象,接口,final)

  • Post author:
  • Post category:java

继承的概述

在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系。
继承:多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承这个父类即可
子类可以直接访问父类中的非私有的属性和行为

 

继承的格式和使用

在程序中,如果想声明一个类继承另一个类,需要使用
extends
关键字。
格式:class 子类
extends
父类
{}
/*
 * 继承:多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去继承这个父类,我们的多个类就可以获取到父类中的成员了。
 * extends
 * 
 */
public class ExtendsDemo {
	public static void main(String[] args) {
		DotA1 d = new DotA1();
		d.start();
		
		LOL1 l = new LOL1();
		l.start();
	}
}
 
class Game1 {
	String name;
	double version;//版本号
	String agent;//代理商
	
	public void start() {
		System.out.println("游戏启动了");
	}
	
	public void stop() {
		System.out.println("游戏关闭了");
	}
}
 
class DotA1 extends Game1 {
	/*String name;
	double version;//版本号
	String agent;//代理商
	
	public void start() {
		System.out.println("游戏启动了");
	}
	
	public void stop() {
		System.out.println("游戏关闭了");
	}*/
}
 
class LOL1 extends Game1 {
	/*String name;
	double version;//版本号
	String agent;//代理商
	
	public void start() {
		System.out.println("游戏启动了");
	}
	
	public void stop() {
		System.out.println("游戏关闭了");
	}*/
	
}

继承的特点


Java
中,类只支持单继承,不允许多继承,也就是说一个类只能有一个直接父类,例如下面这种情况是不合法的。

  class A{}

   class B{}

   class C extends A,B{}  // C类不可以同时继承A类和B

多个类可以继承一个父类,例如下面这种情况是允许的。

  class A{}

   class B extends A{}

   class C extends A{}   // B和类C都可以继承类A


Java
中,多层继承是可以的,即一个类的父类可以再去继承另外的父类,例如
C
类继承自
B
类,而
B
类又可以去继承
A
类,这时,
C
类也可称作
A
类的子类。下面这种情况是允许的。

class A{}

class B extends A{}   // B继承类A,类B是类A的子类

class C extends B{}   // C继承类B,类C是类B的子类,同时也是类A的子类


Java
中,子类和父类是一种相对概念,也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如上面的这种情况中,
B
类是
A
类的子类,同时又是
C
类的父类

/*
 * Java中继承的特点:
 * 			Java语言只支持单一继承,只能继承一个父类(一个儿子只能有一个亲爹)
 * 			Java语言支持多层继承(一个儿子可以有一个亲爹,还可以有一个亲爷爷)
 * 
 */
public class ExtendsDemo2 {
	public static void main(String[] args) {
		LOL l = new LOL();
		l.update();
		l.start();
	}
}
 
class Game {
	public void start() {
		System.out.println("游戏启动了");
	}
}
 
class PCGame extends Game {
	public void update() {
		System.out.println("PCGame更新了");
	}
}
 
class MobileGame extends Game {
	public void update() {
		System.out.println("MobileGame更新了");
	}
}
 
class LOL extends PCGame {
	
}

继承中成员变量的特点

A:
子类只能获取父类非私有成员
子父类中成员变量的名字不一样直接获取父类的成员变量
子父类中成员变量名字是一样的获取的是子类的成员变量
B:
就近原则:谁离我近我  就用谁
如果有局部变量就使用局部变量
如果没有局部变量,有子类的成员变量就使用子类的成员变量
如果没有局部变量和子类的成员变量,有父类的成员变量就使用父类的成员变量
C: super:
可以获取父类的成员变量和成员方法
,
用法和
this
是相似的

方法重写的应用场景和注意事项

方法重写的应用场景:当父类的方法不能完全满足子类使用的时候,既可以保留父类的功能(沿袭、传承),还可以有自己特有的功能
方法重写的注意事项:
不可以重写父类私有的成员方法,压根就看不到父类的私有成员
子类重写父类方法,权限必须大于等于父类方法的权限
注解    @Override:方法重写,说明下面的方法是重写父类的方法

public class ExtendsDemo5 {
	public static void main(String[] args) {
		NewPhone np = new NewPhone();
		np.call();
	}
}
 
class Phone {
	void call() {
		System.out.println("打电话");
	}
}
 
class NewPhone extends Phone {
	
	@Override
	public void call() {
		System.out.println("录音");
		//System.out.println("打电话");
		
		//super.call();
	}
}

继承优缺点:

A:
优点:
提高了代码的
复用性
提高了代码的
可维护性
B:
缺点:
类的耦合性增强了(耦合:类与类的关系 
)
开发的原则:高内聚低耦合
内聚:就是自己完成某件事情的能力

 

final关键字

final
: 修饰符,可以用于修饰类、成员方法和成员变量
final
所修饰的类:不能被继承,不能有子类
final
所修饰的方法
:
不能被重写
final
所修饰的变量:是不可以修改的,是常量
常量:
字面值常量:
1,2,3
自定义常量:被
final
所修饰的成员变量,一旦初始化则不可改变
注意:自定义常量必须初始化,可以选择显示初始化或者构造初始化
public class FinalDemo {
	public static void main(String[] args) {
		//Animal a = new Animal();
		//a.eat();
		
		Dog d = new Dog();
		//d.eat();
		
		//d.num = 20;
		System.out.println(d.NUM);
	}
}
 
/*final*/ class Animal {
	public final void eat() {
		System.out.println("吃东西");
	}
}
 
class Dog extends Animal {
	/*public void eat() {}*/
	
	final int NUM;
	
	public Dog() {
		NUM = 10;
	}
}

 

抽象类概述

当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具体实现方式,那么这些方法都有具体的方法体。
但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。比如一个图形类应该有一个求周长的方法,但是不同的图形求周长的算法不一样。那该怎么办呢?
分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

                

                abstract:关键字,用于修饰方法和类

                抽象方法:不同类的方法是相似,但是具体内容又不太一样,所以我们只能抽取他的声明,没有具体的方法体,没有具体方法体的方法就是抽象方法

                抽象类:有抽象方法的类必须是抽象类(注意:一个类继承了抽象类需要重写他所有的抽象方法,否则这个类就得是抽象类 )

 

public class AbstractDemo {
 
}
 
abstract class Animal1 {
	public abstract void eat();
	
	//非抽象方法子类可以不重写
	public void run() {
		
	}
}
 
class Cat1 extends Animal1 {
 
	@Override
	public void eat() {
		System.out.println("猫吃鱼");
		
	}
	
	/*public void eat() {
		System.out.println("猫吃鱼");
	}*/
}
 
abstract class Dog1 extends Animal1 {
	/*public void eat() {
		System.out.println("狗吃屎");
	}*/
}

抽象类的特点

抽象方法只能在抽象类里面
抽象类和抽象方法必须被
abstract
修饰
抽象类不能创建对象(不能实例化)
抽象类中可以有非抽象的方法
抽象类和类的关系也是继承
一个类继承了抽象类要么重写所有的抽象方法,要么他自己是抽象类

 

public class AbstractDemo2 {
	public static void main(String[] args) {
		//Animal a = new Animal();
	}
}
 
abstract class Animal2 {
	public abstract void eat();
	
	public void run() {
		
	}
}
 
class Cat2 extends Animal2 {
 
	@Override
	public void eat() {
		// TODO Auto-generated method stub
		
	}
 
}

抽象类的成员的特点

成员变量
可以有成员变量
可以有常量
成员方法
可以有抽象方法
可以有非抽象方法
构造方法
可以有构造方法的,需要对抽象类的成员变量进行初始化

 

public class AbstractDemo3 {
	public static void main(String[] args) {
		Dog d = new Dog();
		d.barking();
	}
}
 
abstract class Animal {
	String name = "哮天犬";
	final int num = 10;
	
	public Animal() {
		System.out.println("我是抽象类的构造方法");
	}
	
	public abstract void eat();
	
	public void run() {}
}
 
class Dog extends Animal {
	public void barking() {
		System.out.println(name);
		System.out.println(num);
	}
 
	@Override
	public void eat() {
		// TODO Auto-generated method stub
		
	}
}

 

抽象类的细节

A:
抽象类关键字
abstract
可以和哪些关键字共存?
1.private
私有的方法子类是无法继承到的,也不存在覆盖,而
abstract

private
一起使用修饰方法,
abstract
既要子类去实现这个方法,而
private
修饰子类根本无法得到父类这个方法。互相矛盾。
2.final:
抽象类不能和
final
共存
,
因为抽象类自身无法创建对象
,
我们需要通过子类创建对象
,
一旦抽象类使用
final
关键字
,
那么抽象类就没有子类
抽象方法不能和
final
共存
,
因为抽象方法后期需要被子类重写
,
一旦加
final
无法重写  
       3.static:
                 抽象方法不能和static关键字共存, 
                 因为一旦加static我们就可以通过类名直接访问抽象方法,由于抽象方法没有方法体,没有任何意义,也不允许这样做
B:
抽象类中是否可以不定义抽象方法?
是可以的,那这个抽象类的存在到底有什么意义呢?不让该类创建对象
,
方法可以直接让子类去使用
C:
抽象类是否有构造函数?

,
抽象类的构造函数
,
是由子类的
super
语句来调用
,
用于给抽象类中的成员初始化

 

接口的概述

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

              Java语言的继承是单一继承,一个子类只能有一个父类

              Java语言给我们提供了一种机制,用于处理继承单一的局限性的,接口

              接口:接口是一个比抽象类还抽象的类,接口里所有的方法全是抽象方法,接口和类的关系是实现,关键字为:implements   interface

接口的使用

接口中的方法全是抽象方法
,
直接
new
接口来调用方法没有意义
,Java
也不允许这样干
类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用
implements
其他类
(
实现类
)
实现接口后,就相当于声明:”我应该具备这个接口中的功能”。实现类仍然需要重写方法以实现具体的功能。
格式:

class implements 接口 {

重写接口中方法

}

 在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。

public class InterfaceDemo {
	public static void main(String[] args) {
		BillGates gates = new BillGates();
		gates.code();
	}
}
 
 
class Boss {
	public void manage() {
		System.out.println("管理公司");
	}
}
 
class Programmer {
	public void code() {
		System.out.println("敲代码");
	}
}
 
//比尔盖茨
class BillGates extends Programmer {
	
}

接口中成员的特点

1
、接口中可以定义变量,但是变量必须有固定的修饰符修饰,
public static final
所以接口中的变量也称之为常量,其值不能改变。
2
、接口中可以定义方法,方法也有固定的修饰符,
public abstract
3
、接口不可以创建对象。
4
、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。

接口和类的关系

A:
类与类之间
:
继承关系
,
一个类只能直接继承一个父类
,
但是支持多重继承
B:
类与接口之间
:
只有实现关系
,
一个类可以实现多个接口
C:
接口与接口之间
:
只有继承关系
,
一个接口可以继承多个接口

 

接口优点

1.
类与接口的关系,实现关系,而且是多实现,一个类可以实现多个接口,类与类之间是继承关系,
java
中的继承是单一继承,一个类只能有一个父类,打破了继承的局限性。
2.
对外提供规则(
USB
接口)
3.
降低了程序的耦合性(可以实现模块化开发,定义好规则,每个人实现自己的模块,提高了开发的效率)

接口和抽象类的区别

1.
共性:
不断的进行抽取,抽取出抽象的,没有具体实现的方法
,
都不能实例化(不能创建对象)
2.
区别
1: 
与类的关系
(1)
类与接口是实现关系,而且是多实现,一个类可以实现多个接口,类与抽象类是继承关系,
Java
中的继承是单一继承,多层继承,一个类只能继承一个父类,但是可以有爷爷类
(2)区别
2
: 成员
a.
成员变量
抽象类可以有成员变量,也可以有常量
接口只能有常量,默认修饰符
public static final
b.
成员方法
抽象类可以有抽象方法,也可以有非抽象方法
接口只能有抽象方法,默认修饰符
public abstract
c.
构造方法
抽象类有构造方法,为子类提供
接口没有构造方法

 

 


版权声明:本文为weixin_63156135原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。