第七章 继承 多态 抽象类与接口

类的继承

继承在面对向对象开发思想中是一个非常重要的概念,它使整个程序架构具有一定的弹性在程序中复用一些已经定义完善的类,不仅可以减少软件开发周期,也可以提高软件的可维护性和可扩展性本章节将详细

讲解类的继承

java语言中 每个类只可以继承一个父类

extends 继承语句

父类没有任何变化

public class 父类类名{
 
}

因为java只支持继承 即一个类只能有一个父类 所以一下代码是错的

class Child extends Parent1 Parents2{}

例题7.1代码

package 第七章继承;
 
public class Parent {//创建父类
//父类
	public Parent(){//
		System.out.println("parnt类的构造方法");//输出
	}
}
public class Child extends Parent{//继承父类的整型变量
	public Child() {
		System.out.println("Child的构造方法");//输出
	}
}
public class Demo {
public static void main(String[]args) {//主方法
	new Child();//新建构造方法
}
}

运行结果图:

parnt类的构造方法
Chlid的构造方法

子类 需要继承分类

public class 子类类名 extends 父类类名 {

}

new 调用构造方法

super//父类的意思//继承的另外一种意思

例题7.2在打电话的基础上衍生出手机类

  1. public class Telephone {//父类
    	String button ="button:0~9";//成员属性  10个按建
    	void call(){//拨打电话功能
    		System.out.println("开始拨打电话");//输出
    	}
    }
    public class  Mobile extends Telephone {//extends 继承父类
    	String screen ="screen:液晶电视";//成员属性
    }
    public class Demo2 {
     
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Mobile motto=new Mobile();//调用构造方法
    		System.out.println(motto.button);//输出
    		System.out.println(motto.screen);//输出
    		motto.call();
    	}
     
    }

    运行结果图

 Object类

所有没有指定父类就是Object

只有子类可以重写父类方法

重写:返回参数相同 方法名相同 传入方法相同 只是方法体不同

Object类中包括clone(),finalize(),equals(),toString()等方法 其中常用的两个方法是equals()和toString()方法由于所有的类都是Object类的子类 所以任何类都可以重写Object类的的方法

下面详细描述了Object类中的几个重要方法

getClass方法

getClass()是Object类定义的方法 他会返回对象执行class实例 然后使用此实例调用geiName()方法可以去的类的名称 语法如下

getClass().gername();
可以将getClass()方法与toString()方法的联合使用

toString()方法

toString()方法的功能是将一个对象返回为字符串的形式 他会返回一个String实例 在实际的应用中通常重写toString()方法 为对象提供一个特定的输出模式当这个类转换成字符串或字符串链接时 将自动调用重写的toString()方法如下例题7。3让学生的自我介绍   使用重写toString方法

代码

package 第七章继承;//toStudent
 
public class Student {//类名
	String name;//成员变量name   名字
	int age;//成员变量  年纪
	public Student(String name,int age) {//定义成员变量
		this.name = name;//将参数赋值给成员变量
		this.age=age;//将参数赋值给成员变量
	}
	public String toString() {//转化为共用字符串类型
		return"我叫"+name+",今年"+age+"岁.";
	}
public static void main(String[]args) {//主方法 
	Student s1 =new Student("张三",16);//新建构造对象方法
	System.out.println(s1);//输出
	Student s2 =new Student("lisi",19);//新建构造对象方法
	System.out.println(s2);//输出
}
}

 代码图

  运行结果

例题7.4

使用equals方法

public class People {
	int id;//整型 身份证号码
	String name;//字符串 名字
	
	public People(int id,String name) {//
	this.id=id;//将参数值赋予给类中成员变量
	this.name=name;//将参数值赋予给类中成员变量
	}
	public boolean equals(Object obj) {//重写Object类中的equals()方法
		if(this==obj)//如果参数与本类是同一个对象
			return true;
		if(obj==null)//如果参数是cull
			return false;
		if(getClass()!=obj.getClass())//如果参数与本类类型不同
			return false;
		People other =(People)obj;//将参数强转成本类对象
		if(id!=other.id)
			return false;
		return true;
}
public String toString() {//重写Object类的toString()方法
	return name;
}
public static void main(String[]args) {
	People p1 = new People(220,"tom");
	People p2 = new People(220,"汤姆");
	People p3 = new People(330,"张三");
	Object o= new Object();
	System.out.println(p1+"与"+p2+"是否为同一个人?");
	System.out.println("equals()方法的结果:"+p1.equals(p2));
	System.out.println("==运算符的结果:"+(p1==p2));
	
	
	System.out.println();
	System.out.println(p1+"与"+p3+"是否为同一个人?");
	System.out.println(p1.equals(p3));
	System.out.println(p1+"与"+o+"是否为同一人?");
	System.out.println(p1.equals(o));
}
}

 运行结果图

对象类型的转换

对象类型的转换在java编程中遇到,主要包括向上转型和向下转型操作 本届将详解讲解对象类型转换的内容

向上转型

向上转型可以理解为将子类类型的对象转换为父类类型的对象,即把子类类型的对象直接赋值给父类类型的对象进而实现按照父类描述子类的效果

向上转型:将子类的对象赋值给父类的对象引用

自动类型转换

Animal a=new Animal();

自动类型转换

构建一个Animal的对象 赋值给Animal的a;

向下转型:将父类的对象赋值给子类对象引用

向下转型的时候需要进行强制类型转换

强制类型转换        

Dog a=(Dog)new Animal();

强制转换需要加()中加

使用instanceof关键字来判断对象属性

对象名instanceof 类名

判断对象是否属于一个类或其子类
 

package 第七章继承;
class Quadrangle{}
class Square extends Quadrangle{}
class Circular{}
	public class Dome5 {
	public static void main(String[] args) {
	 Quadrangle q=new Quadrangle();//四边形对象
	 Square s=new Square();//正方形对象
	 System.out.println(q instanceof Square);//判断四边形是否为正方形的子类
	 System.out.println(s instanceof Quadrangle);//判断正方形是否为四边形的子类
	 System.out.println(q instanceof Circular);//判断正方形是否为圆形的子类
	}
	}
	
}

方法的重载

第六章中我们曾学习过构造方法 ,知道构造方法的名称是由类名决定,所以构造方法只有一个格名称。 如果希望以不同的方式俩实例化对象,就需要使用u东哥构造方法来完成 由于这个构造方法都需要根据类名进行命名 为了让方法名相同 而形参不同的构造方法同时存在必须用到方法重载  虽然方法重载起源与构造方法 但是它可以应用在其他方法中

方法的重载就是在同意给类中允许存在的一个以上的同名方法,只要这些方法的参数个数或类型不同即可 详细类容如例题7.8

方法名相同  参数不同;

顺序不一样也叫做参数不同

变量名不重要 类型重要

不定长参数的底层参数是数组

代码图

package 第七章继承;
 
public class OverLoadTest {
	public static int add(int a,int b) {//定义一个方法 
		return a+b;
	}
public static double add(double a,double b) {//与方法名成相同,参数类型不同
	return a+b;
}
public static int add(int a) {//与第一个方法相同参数类型不同
	return a;
}
public static int add(int a,double b) {//先int参数后double参数
	return a;//输出int参数
}
public static int add(double a,int b) {//先double参数后int参数
	return b;//输出int参数值
}
public static int add(int...a) {
	int s =0;
	for(int i=0;
			i<a.length;i++) {
		s+=a[i];
	}
	return s;
}
public static void main(String args[]) {
	System.out.println("调用add(int,int)方法:"+add(1,2));
	System.out.println("调用add(double,double)方法:"+add(2.1,3.3));
	System.out.println("调用add(int)方法:"+add(1));
	System.out.println("调用add(int,double)方法:"+add(5,8.0));
	System.out.println("调用add(double,int)方法:"+add(5.0,8));
	
	System.out.println("调用不定长参数方法"+add(1,2,3,4,5,6,7,8,9));
	System.out.println("调用add(double,int)方法:"+add(1));
}
}

 运行结果图

根据书上图7.6所示的构成方法重载条件 可以总结出编译器时利用方法名,方法个参数类型和参数的个数,参数的顺序来确定类中的方法是否唯一 方法的重载是的方法一种以的名称被管理使程序代码更有条理  。在谈到参数个数可以确定连个该方法是否具有重载关系,会先想到定义不定的长的参数方法 ,不确定长方法的语法入下

返回值 方法名(参数数据类型...参数名称)
 例题7.9使用不定长参数重载方法并输出返回值

7.9跟7.8类似其中加了for循环让每个参数做循环参数

final关键字

final被译为”最后的“”最终的“final时java语言中的关键字 凡是被final关键字修饰过的内容都是不可改变的

final关键字用于修饰常量

final关键字可用于声明变量,一旦该变量被设定 就不可以在改变该变量的值。通常由final定义的变量为常量如以下语句:

final doublie P1= 3.14;

final修饰方法-----该方法不可以被重写

final修饰类-----该类不能被继承

Mymath也不能被重写和继承

例题 7.10 定义不允许被修改的常量Π

创建FinaIData类中 在该类中定义表示圆周率的常量PI,并尝试修改PI的值

package 第七章继承;
 
public class FinalData {
		static final double P1=3.1415926;
		public static void main(String[]args) {
		 System.out.println("圆周率的值为:"+P1);
		 System.out.println("半径为3的元的周长为:"+2*3*P1);
		 P1=3.1415926;
		   }
}

本实例在运行之前Eclipse就会报出错误 常量PI时不允许被修改的

final方法

将方法定义为final类型,可以防止子类修改父类的定义与实现方法 同时定义为final的方法执行效率要高于非final方法 在需要时股权哑巴宣布这个i部分曾经提到过private修饰符 如果一个父类的某个方法被设置为private 子类将无法访问该方法,自然无法覆盖该方法,也就是说一个定义为private的方法隐式被指定为final类型因此无需将一个定义为private的方法在定义为final类型语法如下:

private final voidtest(){
....//省略一些代码程序
}

例题7.11使用final关键字为电视上儿童锁

代码图

package 第七章继承;
 
public class Dad {
public final void turnOntheTV() {
	System.out.println("爸爸打开了电视5");
	}
}
 
 
public class Baby extends Dad{
public final void turnOnTheTV() {
	System.out.println("宝宝也要看电视");
	}
}

此代码编译错误 因为打开电视这个方法是由final修饰的子类无法重写。所以Baby想要打开电视就只能找爸爸来打开

final类

定义为final的类不能被能继承 如果希望一个类不被任何类继承,并且不允许其他人对这个类进行任何改动 可以将这个类设置为final类 final类语法如下:

final类名{}

如果设置为final类,则该类中的所有方法都被影视设置为final方法 但是final类中成员可以被定义为final或非final形式

例如,已知JDK中的java.lang包下的Math 数学类和String字符串类都是由 final关键字修饰的类这两个类就无法做任何类的父类,如果这两个类出现在extends右侧就会发生编译错误。

 class MyMath extends java.lang.Math{}
类型MyMath 不能成为终态类Math的子类
class MyString extends java.lang.String{}5
类型 MyString不能成为修态类 String的子类
 

多态

利用多态可以使程序具有良好的扩展性,并可以对所有类对象进行通用的处理。在7.3已经习过子类对象可以作为父类的对象实例使用,这种将子类对象视为父类对象的做法称为“向上转型”
假如现在要编写一个绘制图形的方法draw(),如果传入正方形对象就绘制正方形,如果传入圆形对象就绘制圆形,这种场景可以使用重载来实现,定义如下:

 

public void draw(Square s){ //绘制正方形的方法 

}
public void draw(Circular c){ //绘制圆形的方法 

}

但是这种写法有个问题:正方形和圆形都是图形,这场景细分的重载方式不仅增加了代码量,还降低了“易用度”。如果定义一个图形类,让它处理所有继承该类的对象,根据“向上转型”原则可以使每个继承图形类的对象作为draw方法的参数,然后在draw方法中做一些限定就可以根据不同形类对象绘制相应的图形。这样处理能够很好地解决代码冗余问题,同时程序也易于维护。


 

class Shape{}//创建一个图形类
class Square extends Shape{}//正方形类继承图形类
class Circular extends Shape{}//圆形类继承图形类
public class winner {
	public static void draw(Shape s) {//绘制方法
		if(s instanceof Square) {//如果是正方形
			System.out.println("绘制正方形");//输出语句
		}else if(s instanceof Circular) {//如果是圆形
			System.out.println("绘制圆形");//输出语句
		}else {//如果是其他图形
			System.out.println("绘制父类图形");//输出语句
		}
	}
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		draw(new Shape());//调用draw方法输出结果
		draw(new Square());
		draw(new Circular());
	}
 
}

运行结果:

 

抽象类和接口

在解决实际问题同时,一般将父类定义为抽象类需要使用这个父类进行继承与多态处理 回想继承和多态原理,继承书中越是在上方的类月抽象,如鸽子类继承鸟类 ,鸟类继承动物类等在多态机制中,并不需要将父类初始化为对象 ,我们需要的只是子类 所以在Java语言中设置抽象类不可以实体化为对象

使用abstract关键字定义的类成为抽象类,而使用这个关键字定义的方法称为抽象方法。抽象方法没有方法体 这个方法本身没有任何意义,除非他被重写,而承载这个抽象方法的抽象必须被继承实际上抽象类除了被继承没有任何意义 定义语法如下:

public abstract class Parent{
    abstract void testAbstract();
}

反过来讲 如果声明一个对象方法,就必须将承载这个抽象方法的类定义为抽象类,不能再非抽象类中获取抽象方法 换句话说只要类中有一个抽象方法,此类被称为抽象类

将绘图方法设为接口方法

代码:

package 第七章继承;
 
interface Paintable{//可绘制接口
	 public void draw();//绘制抽象方法
	}
public class Quadrangle1 {
	public void doAnything() {
		  System.out.println("四边形提供的方法");
		  
		 }
		}
		//平行四边形类,继承四边形类,并实现了可绘制接口
		class Parallelogram extends Quadrangle1 implements Paintable{
		 public void draw() {//由于该类实现了接口,所以需要覆盖draw方法
		  System.out.println("绘制平行四边形");
		 }
		}
		//正方形继承平行四边形,并实现了可绘制接口
		class Squareab extends Quadrangle1 implements Paintable{
		 public void draw() {
		  System.out.println("绘制正方形");
		 }
		}
		//圆形类,仅实现可绘制接口
		class Circularab implements Paintable{//圆形类实现接口
		 public void draw() {
		  System.out.println("绘制圆形");
		 }
		}
public class Demo7 {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Squareab q=new Squareab();//正方形对象
		  q.draw();
		  q.doAnything();
		  Parallelogram p=new Parallelogram();//平行四边形对象
		  p.draw();
		  p.doAnything();
		  Circularab c=new Circularab();//圆形对象
		  c.draw();
 
		 }
	}

 结果:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值