继承是在现有类的基础上构建新的类用来满足新的要求.在继承过程中,新的类继承原来的方法和实例变量,并且能添加自己的方法和变量.
继承是指声明一些类,可以进一步声明这些类的子类,而子类具有父类拥有的一些方法和属性,这跟现实中的父子关系十分相似,所以面向对象把这种机制成为继承.子类也称为派生类.
父类又称基类,超类
子类又称派生类
继承的使用
创建一个Animal动物类
public class Animal {
String type;//种类
String name ; //名字
int age;
int weight;//体重
void eat(){
System.out.println("anmal eat");
}
void breath(){
System.out.println("anmal breath");
}
void sleep(){
System.out.println("anmal sleep");
}
}
创建一个Tiger老虎类
public class Tiger extends Animal {
String tigerType ;
String from ;
void tigerRun(){
System.out.println("the tiger run");
}
}
Tiger类的第一行使用的public class TigerextendsAnimal 表示Tiger类继承Animal类.通过继承,新生的老虎类不仅继承了Animal类的实例变量和方法,
还有自己的所有的字段tigerType,from和tigerRun方法
Tiger类使用如下:
public class TigerDemo {
public static void main(String[] args){
//构建一个Tiger对象
Tiger tiger = new Tiger();
//对tiger的属性进行赋值
tiger.type = "Tiger";
tiger.name = "泰哥";
tiger.age = 12;
tiger.weight = 120 ;
tiger.tigerType = "东北虎";
tiger.from = "长白山";
//打印属性值
System.out.println("Animal属性:种类"+tiger.type);
System.out.println("Animal属性:名字"+tiger.name);
System.out.println("Animal属性:年龄"+tiger.age);
System.out.println("Animal属性:体重"+tiger.weight);
System.out.println("Tiger属性:老虎种类"+tiger.tigerType);
System.out.println("Tiger属性:产地"+tiger.from);
}
}
程序运行结果如下:
子类对象的构造
/**
* * 子类对象的创建过程:
* 从最顶层的基类开始往下一层层的调用默认的构造函数
*/
class A {
A(){
System.out.println("调用A的构造方法");
}
}
class B extends A {
B(){
System.out.println("调用B的构造方法");
}
}
class C extends B {
C(){
System.out.println("调用C的构造方法");
}
}
public class CallConstructor {
public static void main(String[] args) {
C c = new C();
}
}
程序运行结果如下:
/*
D,E,F三个类 E继承了D ,F继承了E,当创建一个F类的时候,会自动调用父类的无参构造函数.
如果想要调用父类的有参构造函数,需要使用super关键字,
调用父类的构造函数的语句要凡在所在方法的第一个语句中
*/
class D {
D(){
System.out.println("调用D的构造行数");
}
D(int i){
System.out.println("调用D的有参构造函数");
}
}
class E extends D{
E(){
System.out.println("调用E的构造行数");
}
E(int i){
super(i);
System.out.println("调用E的有参构造函数");
}
}
class F extends E{
F(){
System.out.println("调用F的构造行数");
}
F(int i){
super(i);
System.out.println("调用F的有参构造函数");
}
}
public class CallConstructor2 {
public static void main(String[] args) {
F f0 = new F();
F f1 = new F(2);
}
}
程序运行结果如下:
如果没有使用super关键字,程序运行结果如下
多态是面向对象语言的又一个重要的特性,多态是指同一个方法根据上下文使用不同的定义的能力; 方法的重载和重写是多态的体现. 重载:是在同一个类方法名相同,参数列表不同
重写:是在具有继承关系类中,方法名和参数列表都相同
public class Animal {
String type;//种类
String name ; //名字
int age;
int weight;//体重
void eat(){
System.out.println("动物吃饭");
}
void breath(){
System.out.println("动物呼吸");
}
void sleep(){
System.out.println("动物睡觉");
}
}
public class Tiger extends Animal {
String tigerType ;
String from ;
void tigerRun(){
System.out.println("泰哥在跑");
}
void breath(){
System.out.println("泰哥用肺呼吸");
}
}
public class Fish extends Animal {
String fishType ;
void swim(){
System.out.println("鱼在游泳");
}
void breath(){
System.out.println("鱼用鳃呼吸");
}
}
public class Dog extends Animal {}
public class OverloadDemo {
public static void main(String[] args){
//声明三个不同的对象
Tiger tiger = new Tiger();
Fish fish = new Fish();
Dog dog = new Dog();
//都调用breath方法
tiger.breath();
fish.breath();
dog.breath();
}
}
运行结果如下:
------------------------------------------------------------------------------------------------------------------------------------------------------
public class Tiger extends Animal {
String tigerType ;
String from ;
void tigerRun(){
System.out.println("泰哥在跑");
}
void breath(){
super.breath();
System.out.println("泰哥用肺呼吸");
}
}
public class OverloadDemo {
public static void main(String[] args){
Tiger tiger = new Tiger();
//调用breath方法
tiger.breath();
}
}
在Animal的子类Tiger中,在breath方法,使用super.breath();调用父类的breath方法.运行结果如下:
Super关键字主要有以下两个用途
在子类的构造方法中调用父类的构造函数
在子类中调用父类方法
----------------------------------------------------------------------------------------
java的多态更多的是跟动态绑定放在一起理解:
动态绑定是一种机制,通过这个机制,对一个已经被重写的方法的调用将会发生在运行的时候,
而不是在编译时解析
class Animal{
String type ;
String name ;
int age ;
int weight;
void eat(){
System.out.println("动物爱吃饭");
}
void breath(){
System.out.println("动物呼吸");
}
void sleep(){
System.out.println("动物在睡觉");
}
}
class Tiger extends Animal{
String tigerType ;
String from ;
void tigerRun(){
System.out.println("老虎在奔跑");
}
void breath(){
System.out.println("老虎是用肺呼吸的");
}
}
class Fish extends Animal{
String fishType ;
void swim(){
System.out.println("鱼在游泳");
}
void breath(){
System.out.println("鱼用鳃呼吸");
}
}
public class Test1 {
public static void main(String[] args) {
Animal[] animals = new Animal[3];
//创建不同的对象,但是都存入Animal的引用中
animals[0] = new Animal();
animals[1] = new Tiger();
animals[2] = new Fish();
animals[0].breath();
animals[1].breath();
animals[2].breath();
}
}
运行结果如下:
存放在Animal数组中的Tiger对象和Fish对象在执行breath方法时,
会自动的调用原来的对象的方法而不是Animal的breath方法,这就是动态绑定.
注意通过数组元素访问方法的时候,只能访问Animal中定义的方法,
对于Tiger类和Fish类定义的方法,却是不能调用的,例如animals[2].swim();就是不正确的;如果要访问这些方法时需要类型装换,例如
public class Test1 {
public static void main(String[] args) {
Animal[] animals = new Animal[3];
//创建不同的对象,但是都存入Animal的引用中
animals[0] = new Animal();
animals[1] = new Tiger();
animals[2] = new Fish();
Test1 t = new Test1();
t.move(animals[0]);
t.move(animals[1]);
t.move(animals[2]);
}
void move(Animal animal){
if(animal instanceof Tiger){
((Tiger)animal).tigerRun();
}else if(animal instanceof Fish){
((Fish)animal).swim();
}else {
animal.sleep();
}
}
}
运行结果如下:
------------------------------------------------------------------------------------------------------------------------
在编写程序的时候需要把类定义的不能继承(称为最终类),或者有的方法不希望被子类继承,这个时候需要使用final关键字来声明.
final class 类名 extends 父类名{
//类体
}
方法也可以被声明为final的,格式如下
修饰符 final 返回值类型 方法名(){
//方法体
}
需要注意的是,实例变量也可以被定义为final ,被定义为final的变量不能被修改,被声明为final的类的方法自动地被声明为final,但是它的实例变量并不是final.
----------------------------------------------------------------------------------------------------------------------------------
抽象类是指在类中定义方法,但是并不去实现它,而在它的子类中去具体的实现.定义的抽象方法不过是一个方法占位符.继承抽象类的子类必须实现父类的抽象方法,除非子类也被定义成一个抽象类.
抽象类是通过abstract关键字实现的,一般形式如下
修饰符 abstract 类名{
//类体
}
抽象方法的定义形式如下
修饰符 abstract 返回值类型 方法名();
注意:在抽象类中的方法不一定是抽象方法,但是含有抽象方法的类必须被定义为抽象类
/*
程序将Animal定义为抽象类,里面的breath方法被定义为抽象方法,
而后面定义为Animal的子类Tiger和Fish都实现了breath方法
*/
public abstract class Animal {
String type ;
String name ;
int age ;
int weight;
void eat(){
System.out.println("动物爱吃饭");
}
abstract void breath();
void sleep(){
System.out.println("动物在睡觉");
}
}
public class Fish extends Animal {
String fishType ;
void swim(){
System.out.println("鱼在游泳");
}
void breath(){
System.out.println("鱼用鳃呼吸");
}
}
public class Tiger extends Animal {
String tigerType ;
String from ;
void tigerRun(){
System.out.println("老虎在奔跑");
}
void breath(){
System.out.println("老虎是用肺呼吸的");
}
}
抽象类的使用
public class AbstractTest {
public static void main(String[] args) {
Animal animal1 = new Fish();
animal1.breath();
Animal animal2 = new Tiger();
animal2.breath();
//以上的都不能直接调用Fish和Tiger类的方法,
// animal1.swim() 和animal2.tigerRun()都是不对的
//正确的使用方法如下:
((Fish)animal1).swim();
((Tiger)animal2).tigerRun();
}
}
运行结果如下:
Java中存在一个非常特殊的类—Object类,他是所有类的祖先类.在java中如果定义一个类,并没有继承任何类,那么它默认继承Object类.如果它继承了一个类,则它的父类,甚至父类的父类一定会继承Object类,所以说所有的类都是Object类的子类.
写的有点儿乱,不过还是希望对大家有所帮助.