继承是多个事物之间存在的一种关系,可以通过is--a(是一个)来判断是否存在继承关系。
特点:
1.事物之间应该具备一定的层次结构,并且具有可传递性。
2.子类继承了父类,那么就继承了父类中所有的属性和方法,但是私有属性和构造方法除外。
子类不能继承父类的构造方法是因为,不能通过子类创建父类的对象。
3.子类继承了父类,子类还可以拥有自己特有的属性和方法。
4.在Java中只支持单一继承,也就是说一个子类只能有一个父类,但是一个父类可以有多个子类。
作用:主要是为了提高代码的重用性
在Java中使用extends关键字实现类与类之间的继承关系
语法:
[访问修饰符] class 子类 extends 父类{
}
示例:
public class Son extends Father{
int age=20;
public void play(){
System.out.println(age);
System.out.println(house+car+money);
makeMoney();
}
public static void main(String[]args){
Son s=new Son();
s.play();
}
}
/**
父类
*/
class Father{
String house="100栋别墅";
String car="a6";
String money="1000000000000000000$";
//private int age=80;
public void makeMoney(){
System.out.println("一天24小时不停得造钱(美元)");
}
}
2.super关键字
前提:super关键字只能出现在有继承关系的子类中。
作用:super表示的是对父类对象的引用。(也就说可以把super看作当前子类的父类对象)
用法:
1.调用父类中的属性和方法
super.属性名称;
super.方法名称(参数列表);
2.明确指明调用父类中的哪个构造方法,此时super关键字一定要出现在子类构造方法的第一句代码
super(参数列表);
注意:
1.在有继承关系的类中,创建子类对象时,一定是先执行父类中的构造方法,然后在执行子类中的构造方法。
2.如果子类构造方法没有显式调用超类构造方法,那么会调用父类的默认构造方法。
3.如果父类没有默认构造方法,而且子类构造方法又没有显示调用父类的其它构造方法,那么编译将报错。此时,需要在子类构造方法中显示调用父类构造方法,则在子类构造方法的第一条语句用关键字 super(参数列表)的形式来调用。
示例:
/**
super关键字的示例
*/
public class Son2 extends Father2{
int age=20;
public Son2(){
super(10);
System.out.println("子类构造方法执行了");
}
public void play(){
System.out.println(super.house+super.car+super.money);
super.makeMoney();
}
public static void main(String[]args){
Son2 s=new Son2();
s.play();
}
}
/**
父类
*/
class Father2{
String house="100栋别墅";
String car="a6";
String money="1000000000000000000$";
//private int age=80;
public Father2(int num){
System.out.println("父类中的构造方法执行了"+num);
}
public void makeMoney(){
System.out.println("一天24小时不停得造钱(美元)");
}
}
private修饰的属性或方法只能在本类中访问。
默认修饰的属性或方法只能在本类或同一个包中的类。
protected修饰的属性和方法只能在本类或同一个包中的类或者不同包内的子类中访问。
注意:protected修饰的属性如果在子类中访问,只能通过父类对象或者直接对属性访问,在子类中不能通过创建父类对象
访问protected修饰的属性。
public修饰的属性和方法任何一个类都可以访问。
注意:类一般用public或默认的修饰符
示例:
/**
访问修饰符
*/
public class Test1{
private int age=20;
public static void main(String[]args){
Test2 t=new Test2();
System.out.println(t.num);
}
}
class Test2{
private String name="zhangsan";
String address="beijing";
protected int num=100;
}
在有继承关系的子类中,才可以发生重写这一多态特征。
定义:在有继承关系的子类中,子类重写父类中的方法,就需要和父类中的方法名称一致,返回类型一致,参数列表一致,而且访问修饰符的范围不能被缩小。
目的:当父类中的方法所完成的功能,满足不了子类的需求时,子类就可以对父类中的方法进行重写。
示例:
/**
重写 示例
*/
public class Son3 extends Father3{
public void makeMoney(){
super.makeMoney();
System.out.println("造人民币");
}
public static void main(String[]args){
Son3 s=new Son3();
s.makeMoney();
}
}
/**
父类
*/
class Father3{
public void makeMoney(){
System.out.println("美元");
}
}
java.lang.Object类是所有Java类的父类
如果在类的声明中未明确使用extends关键字指定父类,则默认为继承自Object类
Object类中的toString()方法,输出对象时格式为:类名@对象哈希码的十六进制整数值
6.final关键字
用法:
1.final修饰变量,那么这个变量其实是一个常量,一旦赋值就不能更改。
2.final修饰方法中的参数,称为最终参数,在方法体中不能再给最终参数赋值。
3.final修饰类,类不能继承。
4.final修饰的方法不能被重写
示例:
/**
final 关键字 示例
*/
public class Test7 extends Test8{
public static void main(String[]args){
final int NUM=100;
// NUM=200;
Test7 t=new Test7();
t.display(100);
}
public void test2(){
}
public void display(final int NUM){
//NUM=1000;
System.out.println(NUM);
}
}
class Test8{
public final void test2(){
}
}
所谓的向上转型,就是把子类对象给父类,可以把对象看作是一个父类对象来使用。
动态绑定机制:在程序运行时,会根据对象的真正的创建者,来决定调用父类或者子类的方法(也就说对象是谁创建的就调用哪个类中的方法)
发生动态绑定机制的条件:
1.要有继承
2.要有重写
3.要有向上转型发生
4.要用向上转型的对象,调用重写的方法。
所谓的向下转型,就是把父类对象给子类,可以把对象看作是一个子类对象来使用。
千万注意:向下转型一定是在向上转型的基础,做类型的还原。不能直接把一个父类对象,强制转换成子类对象。
使用向下转型需要使用强制转换符。
instanceof关键字判断对象是否属于某个类,语法:
对象名称 instanceof 类名(接口名称)
示例1:
/**
向上转型 示例
*/
public class Son4 extends Father4{
public static void main(String[]args){
//发生向上转型
Father4 f=new Son4();
f.test1();
//f.display();//会报错,会找不到display方法,因为此时的对象是父类的类型
}
/*
如果使用向上转型的对象,调用子类中的非重写方法,就可以证明向上转型以后的对象,确实是属于父类这种类型
*/
public void display(){
System.out.println("方法display");
}
public void test1(){
System.out.println("okok");
}
}
/**
父类
*/
class Father4{
public void test1(){
System.out.println("ok");
}
}
示例2:
/**
向下转型 示例
*/
public class Son5 extends Father5{
public static void main(String[]args){
Father5 f=new Son5();
Son5 s=(Son5)f;
s.test();
//Son6 s1=(Son6)f;
System.out.println(f instanceof Father5);
System.out.println(f instanceof Son5);
System.out.println(f instanceof Son6);
Father5 f2=new Father5();
System.out.println(f2 instanceof Son5);
System.out.println(s instanceof Father5);
System.out.println(s instanceof Son6);
}
public void test(){
System.out.println("okok");
}
}
/**
父类
*/
class Father5{
public void display(){
System.out.println("ok");
}
}
class Son6 extends Father5{
}
面向对象编程练习题
1.写一个类,名为Animal,该类有两个私有属性,name(代表动物的名字),和legs(代表动物的腿的条数);要求为两个私有属性提供public 的访问方法。并提供两个重载的构造方法,一个需要两个参数,分别用这两个参数给私有属性name和legs赋值。另一个无参,默认给name赋值为AAA,给legs赋值为4;该类还有两个重载的move()方法,其中一个无参,在屏幕上输出一行文字:XXX Moving!!(XXX为该动物的名字);另一个需要一个int参数n,在屏幕上输出n次 XXX Moving!!
2.写一个类Fish,继承自Animal类,并提供一个构造方法,该构造方法需要一个参数name,并给legs赋默认值0;该类还要求覆盖Animal类中的无参move()方法,要求输出:XXX Swimming!!
3.写一个类Bird,继承自Animal类,并提供一个构造方法,该构造方法需要一个参数name,并给legs赋默认值2;该类还要求覆盖Animal类中的无参move()方法,要求输出:XXX Flying!!
4.写一个类Zoo,定义一个主方法,在主方法中分别生成若干个Animal,Fish和Bird。并调用他们的属性和方法。(用上多态)
5. 请编码实现如下需求。乐器(Instrument)分为:钢琴(Piano)、小提琴(Violin);各种乐器的弹奏( play )方法各不相同。编写一个测试类InstrumentTest,要求:编写方法testPlay,对各种乐器进行弹奏测试。要依据乐器的不同,进行相应的弹奏。在main方法中进行测试。
6. 请编码实现动物世界的继承关系:动物(Animal)具有行为:吃(eat)、睡觉(sleep);动物包括:兔子(Rabbit),老虎(Tiger);这些动物吃的行为各不相同(兔子吃草,老虎吃肉);但睡觉的行为是一致的。请通过继承实现以上需求,并编写测试类AnimalTest进行测试。
第三章:面向对象题2
1. 请编码实现如下需求。乐器(Instrument)分为:钢琴(Piano)、小提琴(Violin);各种乐器的弹奏( play )方法各不相同。编写一个测试类InstrumentTest,要求:编写方法testPlay,对各种乐器进行弹奏测试。要依据乐器的不同,进行相应的弹奏。在main方法中进行测试。
2. 请编码实现动物世界的继承关系:动物(Animal)具有行为:吃(eat)、睡觉(sleep);动物包括:兔子(Rabbit),老虎(Tiger);这些动物吃的行为各不相同(兔子吃草,老虎吃肉);但睡觉的行为是一致的。请通过继承实现以上需求,并编写测试类AnimalTest进行测试。
3.定义一个电器类,然后分别定义它的两个子类:电视机和电脑,再定义一个判定类判定在动态运行时是哪台电器在运行。
说明:动态运行其实就是动态绑定机制