java继承多态抽象简单实例_java第四节 类的继承/抽象/接口/多态性

/*

类的继承

类的继承可以简化类的定义

java只支持单继承,不允许多重继承

可以有多层继承,即一个类可以继承其一个类的子类,如类B继承了类A,类C又可以继承类B

那么类C也间接继承了类A

子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法,

在子类的构造方法中可使用语句super(参数列表)

调用父类的构造方法

如果子类的构造方法中没有显式地调用父类构造方法,也没用使用this关键字调用重载的其它构造方法,则在产生子类的实例对象时

系统默认调用父类无参数的构造方法

子类对象的实例化过程

1 分配成员变量的存储空间并进行默认的初始化,就是用new关键字产生对象后

对类中的成员变量按第三章的表3.1的对应关系对对象中的成员变量进行初始化赋值

2 绑定构造方法参数,就是new Person(实际参数列表)中所传递进的参数赋值给构造方中的形式参数变量

3 如果有this()调用,则调用相应的重载构造方法(被调用的重载构造方法又从步骤2开始执行这些流程)

被调用的重载构造方法的执行流程结束后,回到当前构造方法,当前构造方法直接跳转到步聚6执行

4 显示或隐式追溯调用父类的构造方法(一直到Ojbect类为止,Object是所有java类的最顶层父类)

在本音后面部分有详细讲解,父类的构造方法又从步骤2开始对父类执行这些流程,父类的构造方法的执行流程结束后,回到当前构造方法,当前构造方法继承往下执行

5 进行实例变量的显示初始化扣喺,也就是执行在定义成员变量时就对其进行赋值的语句

6 执行当前构造方法的方式体中的程序代码

1):为什么super()和this()调用语句不能同时在一个构造函数中出现?

因为当在一个构造函函数中出现this()调用以后,那么去别外一个构造函数将也会直接默认或指定的super()方法

如要执行完成以后,返回到初始的构造函数还让执行super()方法时,那就又是重复操作了,无意义

所以编译也不会通过的

2):为什么super()和this()调用语句只能作为构造函数的第一句出现

如果不是作为第一句出现,编译也会出错的

如果选执行一些赋值语句,然后执行this或super()函数

那么就跟我们的执行流程相矛盾了

因为构造函数需要需要执执行this,如果没有this执行super()方法

编译器也不会让通过的

覆盖父类的方法

覆盖方法必须和被覆盖方法具有相同的方法名称,参数列表和返回值类型

如果在子类中想调用父类中那个被覆盖的方法,我们可以用super方法的格式

覆盖方法时,不能使用此父类中被覆盖的方法更严格的访问权限

final关键字

1 在java中声明类,属性和方法时,可以使用关键字final来修饰

2 final标记的类不能被继承

3 final标记的方法不能被子类重写

4 final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次

5 方法中定义的内置类只能访问该方法内的final类型的局部变量

用final定义的局部变量相当于是一个常量,它的生命周期超出了方法运行的重命周期

将一个行参定义成final也是可以的,这就是限定了我们在方法中修改形式参数的值

6 public static final共同标记常量时,这个常量就成了全局常量

抽象类

java中可以定义一些不含方法体的方法,它的方法体的实现交给该类的子类根据自己的情况去实现

这样的方法就是抽象方法,包含抽象方法的类叫做抽象类

1 抽象类必须使用abstract关键字来修饰,抽象方法也必须用abstract来修饰

2 抽象类不能被实例化,也就是不能用new关键字去产生对象

3 抽象类只需声明,而不需实现

4 含有抽象方法的类必须声明为抽象类,抽象类的子类必须覆盖所有抽象方法后才能被实例化,否则这个子类还是个抽象类

*/

//final class Person 将不能被继承了

class Person

{

//protected final String name = "unknown"; 变量为final时将不能被子类赋值了

protected String name = "unknown";

//public final String x = "abc"; //第一种赋值是初始赋值

public final String x;

//public static final String x;

public static final String y = "abc";

public int age = -1;

public Person()

{

this.x = "cde";

}

public Person(String name, int age)

{

this.name = name;

this.age = age;

//或者在构造函数中进行赋值

this.x = "abc";

}

//public void getInfo(){} 将不能在子类重写了

public void getInfo()

{

//this.x = "abc"; //用final定义的变量将不能被修改了

System.out.println("name:"+name+", age:"+age);

}

};

class Student extends Person

{

public String school = "unknown";

public Student()

{

//super("xlc",15);

super();

}

public Student(String name, int age, String school)

{

this(name,age); //调用自己的构造函数

this.school = school;

//this(name,age); //调用自己的构造函数

}

public Student(String name, int age)

{

super(name, age);

}

public void getInfo()

{

System.out.println("school:"+school+"name:"+name+", age:"+age);

super.getInfo();

}

public void study()

{

}

};

class TestStudent

{

public static void main(String[] args)

{

//Student st = new Student();

//st.name = "xlc";

//st.age = 34;

//st.getInfo();

Student st = new Student("xlc",22,"清华大学");

st.getInfo();

System.out.println(Float.MAX_VALUE);

}

};

/*

接口(interface)

如果一个抽象类中的所有方法都是抽象的,我们就可以将这个类用另外一种方式来定义,也就是接口定义

接口是抽象方法和常量值的定义的集合,从本质上讲,接口是一种特殊的抽象类

这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现

1 接口中的成员都是public访问类型的,接口的变量默认是用public static final标识的

2 我们可以定义一个新的接口用extends 关键字去继承一个已有的接口

3 我们也可以定义一个类用implements关键字去实现一个接口中的所有方法,我们还可以去定义一个抽旬类用implements关键字去实现一个接口中定义的部分方法

4 一个类可以继承一个父类的同时,实现一个或多个接口,extneds关键字必须位于implements关键字之前

对象的类型转换

1 子类对象可以自动转换成父类

2 父类转换为子类必须使用强制转换

3 instanceof操作符可以用它来判断一个实例对象是否属于一个类

4 Object类及equals方法

*/

/*abstract class A

{

abstract int aa(int x, int y);

//抽象类将不能实例化

};

class B extends A

{

int aa(int x, int y)

{

return 1;

}

};*/

interface Runner

{

int ID = 1;

void run();

}

interface Animal extends Runner

{

void breathe();

}

class Fish implements Animal

{

public void run()

{

System.out.println("fish is swimming");

}

//public void breathe()

public void breathe()

{

System.out.println("fish is bubbling");

}

public static void main(String[] args)

{

Fish f = new Fish();

int j=0;

j = Runner.ID;

j = f.ID;

//f.ID = 2; //常量不能被赋值

}

};

abstract class LandAnimal implements Animal

{

public void breathe()

{

}

};

interface dog

{

void uaau();

}

interface Flyer

{

void fly();

}

class Bird implements Runner, Flyer

{

public void run()

{

}

public void fly()

{

}

};

//继承一个类时,可以实现其它接口

//也是可以继承从外接口类的

class Student extends Person implements Runner, dog

//如果继承类和接口,extends必须在implements之前

{

public void run()

{

}

public void uaau()

{

}

};

interface A

{

//public static final int ID=1;

//int ID = 1; //这个是一个常量而不是一个变量,接口只能定义常量,不能定义变量,

//只能定义常量和抽象类

public static final int ID=1;

int aa(int x, int y);

void bb();

}

/*class

{

public static void main(String[] args)

{

System.out.println("Hello World!");

}

}*/

/*

面向对象的多态性

1):应用程序不必为每一个派生类(子类)编写功能调用

只需要对抽象基类进行处理即可,这一招叫"以不变应万变",可以大大提高程序的可复用性

2):派生类的功能可以被基类的引用变量引用,这叫向后兼容,可提高程序的可扩充性和可维护性

以前写的程序可以被后来程序调用不足以为奇,现在写的程序(如callA方法)能调用以后写的程序(以后编写的一个类A的子类,如类D)就了不起了

*/

class A

{

public void func1()

{

System.out.println("A func1 is calling");

}

public void func2()

{

func1();

}

};

class B extends A

{

public void func1()

{

System.out.println("B func1 is calling");

}

public void func3()

{

System.out.println("B func3 is calling");

}

};

class C

{

public static void main(String[] args)

{

B b = new B();

callA(b);

//A aa = b;

//callA(new A());

}

public static void callA(A a)

{

/*if(a instanceof B)

{

B b = (B)a; //强制类型转换

b.func1();

b.func2();

b.func3();

}else{

a.func1();

a.func2();

}*/

a.func1();

a.func2();

//a.func1();

//a.func2();

//a.func3();

}

};

class Student extends Object

{

private String name;

private int age;

public Student(String name, int age)

{

this.name = name;

this.age = age;

}

/*public boolean equals(Object obj)

{

Student st = null;

if(obj instanceof Student)

{

st = (Student)obj;

if(st.name == name && st.age == age)

{

return true;

} else{

return false;

}

}else{

return false;

}

}*/

//如果没有覆盖父类的equals方法,那么将返回不等

//只是重载了一下函数

public static void main(String[] args)

{

Student st1 = new Student("张三",20);

Student st2 = new Student("张三",20);

if(st1.equals(st2))

{

System.out.println("相等");

}else{

System.out.println("不相等");

}

}

};

/*class

{

public static void main(String[] args)

{

System.out.println("Hello World!");

}

}*/

interface PCI

{

void start();

void stop();

}

class NetWrokCard implements PCI

{

public void start()

{

System.out.println("Send...");

}

public void stop()

{

System.out.println("stop...");

}

};

class SoundCard implements PCI

{

public void start()

{

System.out.println("du...");

}

public void stop()

{

System.out.println("sound stop...");

}

};

class MainBoard

{

public void usePCICard(PCI p)

{

p.start();

p.stop();

}

};

class Assembler

{

public static void main(String[] args)

{

MainBoard mb = new MainBoard();

NetWrokCard nc = new NetWrokCard();

SoundCard sc = new SoundCard();

mb.usePCICard(nc);

mb.usePCICard(sc);

//匿名类

/*mb.usePCICard(

new PCI()

{

public void start()

{

System.out.println("test start...");

}

public void stop()

{

System.out.println("test end...");

}

}

);*/

//类拟于

class A implements PCI

{

public void start()

{

System.out.println("test start...");

}

public void stop()

{

System.out.println("test end...");

}

};

mb.usePCICard(new A());

}

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
继承:在面向对象编程中,继承是指一个(子)可以从另一个(父继承属性和方法的过程,子可以添加自己的属性和方法,从而复用父的代码。 抽象类抽象类是不能直接实例化的,它的主要目的是作为其他的基,并提供一个似于接口的设计模式。抽象类可以包含实例变量和非抽象方法的实现,但其中至少有一个抽象方法需要由子去实现。 接口接口是一个规范,它定义了之间的交互方式。接口中只有方法的声明,没有方法的实现,因此每个实现都需要实现接口中的所有方法。 多态多态是指同一型的对象,在不同的情况下可能会产生不同的行为。在面向对象编程中,多态性是一个对象(如接口抽象类等)表现出多种型或行为的能力。 构造函数:构造函数是一种特殊的方法,用于创建和初始化对象。每次创建的新实例时,构造函数都会被调用一次。 static:static 关键字用于声明静态成员变量或静态方法。静态方法属于整个,可以通过名调用,而不需要创建实例。静态变量是共享的,在所有实例中保持相同的值。 final:final 关键字可以用于修饰、方法或变量,它表示不可改变或不可继承。当一个被声明为 final 时,它将不能被其他继承。当一个方法被声明为 final 时,它将不能被重写。当一个变量被声明为 final 时,它将不能被重新赋值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值