首先先了解几个知识点:
1、final关键字:final关键字可以修饰类、成员变量和方法中的局部变量。
①final关键字将类声明为final类,final类不能被继承,既不能有子类。
②final关键字修饰方法:如果用final修饰父类中的一个方法,那么这个方法不允许子类重写,也就是说,不允许子类隐藏可以继承的final方法(老老实实继承,不允许做任何修改)
③final修饰常量:如果用final修饰成员变量和局部变量,那它就是常量。常量在运行期间不允许再发生变化,所以用final修饰常量时必须声明初值。
2、上转型对象:
①假设Animal类是Tiger类的父亲,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时:
Animal a;
a=new Tiger();
或
Animal a;
Tiger b = new Tiger();
a=b;
这时称对象a是对象b的上转型对象(就比如说“老虎是动物”).
②上转型对象具有的特点:
(1)上转型对象不能操作子类新增的成员变量(失掉了部分属性),不能调用子类新增的方法(失去了一些行为)。
(2)上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。
注意:*可以将对象的上转型对象再强制转换到一个子类对象
*不可以将父类创建的对象的引用赋值给子类声明的对象
*如果子类重写了父类的静态方法,那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法
一、面向抽象编程
1、abstract类和abstract方法
用关键字abstract修饰的类称为抽象类,用abstract修饰的方法称为抽象方法。
①对于abstract方法,只允许声明,不允许实现(没有方法体),而且不允许使用final和abstract同时修饰一个方法或类,也不允许使用static修饰abstract方法,即abstract方法必须是实例方法。
②abstract类中可以有非abstract方法,但是非abstract类中一定不能有abstract方法。
③sbstract类不能用new运算符创建对象。
④如果一个非abstract类是abstract的子类,它必须重写父类的abstract方法,即去掉abstract方法的abstract修饰,并给出方法体。如果一个abstract类是abstract类的子类,它可以重写父类的abstract方法,也可以继承父类的abstract方法。
⑤abstract类的对象作上转型对象:可以使用abstract类声明对象,尽管不能使用new运算符创建该对象,但是该对象可以成为其子类对象的上转型对象,那么该对象就可以调用子类重写的方法。
2、继承中成员变量的特点:
①子类只能获取父类非私有成员
子父类成员变量的名字不一样直接获取父类的成员变量
子父类成员变量名字一样直接获取子类的成员变量
②就近原则:谁离我近我就用谁(隐藏父类变量或方法)
如果有局部变量,就直接使用局部变量
如果没有局部变量,有子类的成员变量就使用子类的成员变量
如果没有局部变量和子类的成员变量,有父类的成员变量就使用父类的成员变量
啥都没有,出错了!
③super:可以获取父类的成员变量和成员方法,用法和this是相似的。
3、继承中成员方法的特点:
- 子类中没有这个方法,调用父类的
- 子类中有这个方法,调用子类的
方法的重写:在子父类中,子类的方法和父类的完全一样,子类重写了父类的方法(覆盖),当子类重写了父类的方法之后,使用子类对象调用的方法就是子类的方法
方法的重载:在一个类中, 有多个重名的方法,但是其参数不一样(参数的个数,参数的类型,参数的顺序),和返回值无关
4、方法重写的应用场景和注意事项:
方法重写的应用场景:
当父类的方法不完全满足子类使用,这个时候子类重写父类的方法,并可以在方法中使用关键字super调用父类的方法,这样做即可以保有父类的功能,也可以调用子类特有的功能
方法重写的注意事项:
不能重写父类私有的方法
权限必须大于等于父类方法的权限
5、继承中构造方法执行顺序:
①在有子父类继承关系的类中,创建子类的对象,调用子类的构造方法
②如果子类构造方法的第一行代码没有调用父类的构造方法,则会默认的调用父类的无参构造
③肯定会先执行父类的构造,因为要先给父类的成员变量进行初始化,子类可能会使用到父类
我们可以使用super()在子类构造方法的第一行中调用父类的构造方法,同一个类中的引用使用this()
5、this和super区别
this和super的区别
this:
当前对象的引用
调用子类的成员变量
调用子类的成员方法
在子类的构造方法第一行调用子类其他构造方法
super:
子类对象的父类引用
调用父类的成员变量
调用父类的成员方法
在子类的构造方法第一行调用父类的构造方法
package ShuFU;
public class thisSuperDemo {
public static void main(String[] args) {
Zi zi=new Zi();
zi.function();
}
}
class Die{
int num=20;
public Die(){
System.out.println("我是父类无参构造");
}
public Die(int a) {
System.out.println("我是父类有参构造");
}
public void show() {
System.out.println("我是父类方法");
}
}
class Zi extends Die{
int num=50;
public Zi() {
this(1);
System.out.println("我是子类无参构造");
}
public Zi(int a) {
System.out.println("我是子类有参构造");
}
public void show() {
System.out.println("我是子类方法");
}
public void function() {
this.num=10;
System.out.println(num);
this.show();
super.num=30;
System.out.println(super.num);
super.show();
}
}
6、继承的优缺点
==优点:==提高了代码的复用性
提高了代码的可维护性
==缺点:==类的耦合性增强了
开发的原则:高内聚低耦合
内聚:就是自己完成某件事的能力
耦合:类与类之间的关系
7、抽象类概述
abstract:关键字,用于修饰抽象类
抽象方法:
不同类的方法是相似,但是具体内容又不太一样,所以我们只能抽取他的声明,没有具体 的方法体,没有具体方法体的方法就是抽象方法。
抽象类:
有抽象方法的类必须是抽象类
注意:
一个类继承了抽象类要重写他所有的抽象方法,否则这个类就得是抽象类
二、面向接口编程
1、接口
使用interface来定义一个接口。例如:
interface Printable{
final int MAX=100;
void add();
float sun(float x,folat y);
}
①接口体:
接口体中只有抽象方法,没有普通的方法,接口体中的变量一定是public static final修饰,方法一定是public abstract抽象方法。接口中没有构造方法。例如:
interface Printable{
public static final int MAX=100;
public abstract void add();
public abstract float sum(float x,float y);
}
②重写接口中的方法:
如果一个非抽象类实现了某个接口,那么这个类必须重写这个接口中所有方法。
如果一个类声明实现一个接口,但没有重写接口中所有方法,那么这个类必须是抽象类,也就是说,抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法。
例如:
interface Computable{
final int MAX=100;
void speak(String s);
int f(int x);
float g(float x,float y);
}
abstract class A implements Computable{
public int f(int x){
int sum=0;
for(int i=1;i<=x;i++){
sum+=i;
}
return sum;
}
}
③接口回调:
例子:
public interface ShowMessage {
void 显示商标(String s);
}
public class TV implements ShowMessage{
public void 显示商标(String s) {
System.out.println(s);
}
}
public class PC implements ShowMessage {
public void 显示商标(String s) {
System.out.println(s);
}
}
//接口回调
public class JieKouDemo {
public static void main(String[] args) {
ShowMessage sm;
sm=new TV();
sm.显示商标("长城牌电视机");
sm=new PC();
sm.显示商标("联想奔月PC机");
}
}
④接口参数:
如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。
例子:
interface SpeakHello {
void speakHello();
}
class Chinese implements SpeakHello {
public void speakHello() {
System.out.println("你好,吃了吗");
}
}
class English implements SpeakHello{
public void speakHello() {
System.out.println("hello,are you ok?");
}
}
class KindHello {
public void lookHello(SpeakHello hello) {
hello.speakHello();
}
}
public class Test {
public static void main(String[] args) {
KindHello kindhello = new KindHello();
kindhello.lookHello(new Chinese());
kindhello.lookHello(new English());
}
}
⑤abstract类与接口的比较:
1、abstract类和接口都可以有abstract方法。
2、接口中只可以有常量,不能有变量;而abstract类中既可以有常量,也可以有变量。
3、abstract类中也可以有非abstract方法,接口不可以。
在设计程序时应当根据具体的分析来确定是使用抽象类还是接口。abstract类除了提供重要的需要子类重写的abstract方法外,也提供了子类可以继承的变量和非abstract方法。如果某个问题需要使用继承才能更好地解决,例如,子类除了需要重写父类的abstract方法,还需要从父类继承一些变量或继承一些重要的非abstract方法,就可以考虑用abstract类。如果某个问题不需要继承,只是需要若干个类给出某些重要的abstract方法的实现细节,就可以考虑使用接口。
2、接口概述
java语言的继承是单一继承,一个子类只能有一个父类(一个儿子只能有一个爹)
java语言给我们提供了一种机制,用于处理继承单一的局限性,接口
接口(interface):接口是一个比抽象类还抽象的类,接口里所有的方法全是抽象方法,接口和类的关系是实现,implements
格式:
interface 接口名{
}
3、接口的成员特点
接口的成员特点:
只能有抽象方法
只能有常量
默认使用public&abstract修饰方法
只能使用public&abstract修饰方法
默认使用public static final修饰变量
只能知识public static final修饰变量
建议:建议大家手动给上默认修饰符
注意:接口不能创建对象(不能实例化)
4、接口和类之间的各种关系
只要是继承关系,只有单一继承,可以多层继承,而实现关系可以有多实现
类与类:继承关系,单一继承,多层继承
类与接口:实现关系,多实现
接口与接口:继承关系,多层继承
5、接口的优点
6、接口与抽象类的区别
7、运动员案例分析
package ShiFU3;
public class Test1 {
public static void main(String[] args) {
LanQiuAthlete lqa=new LanQiuAthlete();
lqa.name="易建联";
lqa.age=30;
lqa.sex="男";
lqa.study();
lqa.sleep();
lqa.eat();
}
}
//定义人类
class Person{
String name;
int age;
String sex;
public Person() {
}
public Person(String name,int age,String sex) {
this.name=name;
this.age=age;
this.sex=sex;
}
public void eat() {
System.out.println("八点开始吃饭");
}
public void sleep() {
System.out.println("十点准时睡觉");
}
}
//定义运动员抽象类
abstract class Athlete extends Person{
public abstract void study();
}
//定义教练抽象类
abstract class Coach extends Person{
public abstract void teach();
}
class PingPangAthlete extends Athlete{
@Override
public void study() {
System.out.println("学习乒乓球抽球");
}
}
class LanQiuAthlete extends Athlete implements Board{
@Override
public void study() {
// TODO 自动生成的方法存根
System.out.println("学习篮球扣篮");
}
@Override
public void GoBoard() {
System.out.println("学英语");
}
}
interface Board{
public abstract void GoBoard();
}
class LanQiuCoach extends Coach implements Board{
@Override
public void teach() {
// TODO 自动生成的方法存根
System.out.println("教扣篮");
}
@Override
public void GoBoard() {
System.out.println("学习英语");
}
}
class PingPangCoach extends Coach{
@Override
public void teach() {
// TODO 自动生成的方法存根
System.out.println("教抽球");
}
}
面向接口编程举例:
//创建接口
interface Advertisement{
public void showAdvertisement();
public String getCorpName();
}
class WhiteCloudCorp implements Advertisement{
public void showAdvertisement() {
System.out.println("*****************");
System.out.println("飞机中的战斗机,欧yes!");
System.out.println("*****************");
}
public String getCorpName() {
return "白云有限公司";
}
}
class BlackLandCorp implements Advertisement{
public void showAdvertisement() {
System.out.println("***********");
System.out.println("劳动是爹\n 土地是妈\n");
System.out.println("***********");
}
public String getCorpName() {
return "黑土集团";
}
}
//负责创建广告牌
class AdvertisementBoard{
public void show(Advertisement adver) {
System.out.println(adver.getCorpName()+"的广告词如下:");
adver.showAdvertisement();//接口回调
}
}
public class Test {
public static void main(String[] args) {
AdvertisementBoard board = new AdvertisementBoard();
board.show(new WhiteCloudCorp());
board.show(new BlackLandCorp());
}
}
运行截图: