final
final:最终的意思,可以修饰类,成员方法,成员变量
特点:
final可以修饰类,该类不能被继承。
final可以修饰方法,该方法不能被重写。
final可以修饰变量,该变量不能被重新赋值,这个变量就是常量。
常量:
字面值常量
"hello",10,true
自定义常量
final int x = 10;
final修饰局部变量的问题
基本类型:基本类型的值不能发生改变
引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。
final修饰变量的初始化时机
被final修饰的变量只能赋值一次。
在构造方法完毕前。(非静态的常量)
多态
多态:同一个对象(事物),在不同时刻体现出来的不同状态。
举例:
猫是猫,猫是动物。
水(液体,固体,气态)
多态的前提:
要有继承关系。
要有方法重写。
要有父类引用指向子类对象。
父 f = new 子();
多态中的成员访问特点:
成员变量
编译看左边,运行看左边(即只能访问父类中的成员变量)
构造方法
创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
成员方法
编译看左边,运行看右边。(编译访问父类,运行先访问子类因为方法重写把父类方法覆盖掉)
静态方法
编译看左
边,运行看左边(静态和类相关,算不上重写,所以访问还是父类)
由于成员方法存在方法重写,所以它运行看子类。
多态的好处
提高了代码的维护性(继承保证)
提高了代码的扩展性(由多态保证)
class Animal1{
public Animal1() {
}
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
class Cat1 extends Animal1{
public Cat1() {
}
public void eat() {
System.out.println("猫吃鱼");
}
public void sleep() {
System.out.println("猫趴着睡觉");
}
}
class Dog1 extends Animal1{
public Dog1() {
}
public void eat() {
System.out.println("狗吃肉");
}
public void sleep() {
System.out.println("狗站着睡");
}
}
class Animal1Tool{
private Animal1Tool() {
}
public static void useAnimal1(Animal1 a) {
a.eat();
a.sleep();
}
}
public class AnimalTest {
public static void main(String[] args) {
Animal1 c = new Cat1();
Animal1 c1 = new Cat1();
Animal1 c2 = new Cat1();
Animal1Tool.useAnimal1(c);
Animal1Tool.useAnimal1(c1);
Animal1Tool.useAnimal1(c2);
System.out.println("-----------------");
Dog1 d = new Dog1();
Dog1 d1 = new Dog1();
Dog1 d2 = new Dog1();
Animal1Tool.useAnimal1(d);
Animal1Tool.useAnimal1(d1);
Animal1Tool.useAnimal1(d2);
}
}
-----------------------------------------------------------------
结果:
猫吃鱼
猫趴着睡觉
猫吃鱼
猫趴着睡觉
猫吃鱼
猫趴着睡觉
-----------------
狗吃肉
狗站着睡
狗吃肉
狗站着睡
狗吃肉
狗站着睡
多态的弊端:
不能使用子类的特有功能。
解决方法:
创建子类对象调用方法即可。(可以,但是很多时候不合理,且占内存)
把父类的引用强制转换为子类的引用。(向下转型)
对象间的转型问题:
向上转型:(从子到父,父类引用指向子类对象)
Fu f = new Zi();
向下转型:(从父到子,父类引用转为子类对象)
Zi z = (Zi) f; (要求该 f 必须时能够转换为Zi的。)
class Animal2{
public void eat() {
System.out.println("吃饭");
}
}
class Cat2 extends Animal2 {
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫玩捉迷藏");
}
}
class Dog2 extends Animal2{
public void eat() {
System.out.println("狗吃肉");
}
public void LookDoor() {
System.out.println("狗看门");
}
}
public class DuoTaiCatDog {
public static void main(String[] args) {
Animal2 a = new Cat2();
a.eat();
System.out.println("--------");
Cat2 c = (Cat2)a;
c.eat();
c.playGame();
System.out.println("---------");
a = new Dog2();
a.eat();
System.out.println("--------");
Dog2 d =(Dog2)a;
d.eat();
d.LookDoor();
}
}
---------------------------------------------------------------
结果:
猫吃鱼
--------
猫吃鱼
猫玩捉迷藏
---------
狗吃肉
--------
狗吃肉
狗看门
抽象类的概述:
动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
抽象类的特点:
抽象类和抽象方法必须用abstract关键字修饰
格式:
abstract class 类名{}
public abstract void eat(); (抽象方法不能有方法体)
抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类。
抽象类不能实例化,因为它不是具体的。不能创建对象。
抽象类有构造方法,但是不能实例化,构造方法是用于子类访问父类数据的初始化
抽象的子类
如果不重写抽象方法,该子类是一个抽象类。
重写所有的抽象方法,这时候子类是一个具体的类。
抽象类的实例化是靠具体的子类实现的。多态的方法。
抽象类的成员特点:
成员变量:既可以是变量,也可以是常量。
构造方法:用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的。
抽象类成员方法特性:
抽象方法 强制要求子类做的事情。
非抽象方法 子类继承的事情,提高代码复用性。
//抽象类
abstract class Animall{
//姓名
private String name;
//年龄
private int age;
//无参构造
public Animall() {
}
//带参构造
public Animall(String name,int age) {
this.name=name;
this.age=age;
}
//抽象方法
public abstract void eat();
//getXxx()/setXxx()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Catt extends Animall{
//无参构造
public Catt() {
}
//带参构造
public Catt(String name,int age) {
super(name,age);
}
//重写方法
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dogg extends Animall{
//无参构造
public Dogg() {
}
//带参构造
public Dogg(String name,int ags) {
super(name,ags);
}
//重写方法
public void eat() {
System.out.println("狗吃肉");
}
}
public class AbstractTest {
public static void main(String[] args) {
//方式一
Catt c = new Catt();
c.setName("花花");
c.setAge(2);
c.eat();
System.out.println(c.getName()+"---"+c.getAge());
//方式二
Catt c2 = new Catt("花花",2);
c2.eat();
System.out.println(c2.getName()+"---"+c2.getAge());
System.out.println("-----------------");
//方式三
Animall a = new Dogg(); //多态
a.setName("旺财");
a.setAge(3);
a.eat();
System.out.println(a.getName()+"---"+a.getAge());
//方式四
Animall a2 = new Dogg("旺财",3);
a2.eat();
System.out.println(a2.getName()+"---"+a2.getAge());
}
}
----------------------------------------------------------------------------------------
结果:
猫吃鱼
花花---2
猫吃鱼
花花---2
-----------------
狗吃肉
旺财---3
狗吃肉
旺财---3
//抽象员工类
abstract class Employ{
//姓名
private String name;
//员工号
private String id;
//薪资
private int salary;
//无参构造
public Employ() {
}
//带参构造
public Employ(String name,String id,int salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
//getXxx()/setXxx()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
//抽象方法工作
public abstract void work();
}
//普通员工类
class personnel extends Employ{
//无参构造
public personnel() {
}
//带参构造
public personnel(String name,String id,int salary) {
super(name,id,salary);
}
//方法重写
public void work() {
System.out.println("按照需求写代码");
}
}
//经理类
class manager extends Employ{
//奖金
private int bonus;
//无参构造
public manager() {
}
//带参构造
public manager(String name,String id,int salary,int bonus) {
super(name,id,salary);
this.bonus = bonus;
}
//getXxx()/setXxx
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
//方法重写
public void work() {
System.out.println("与客户谈需求");
}
}
public class EmployeeTest {
public static void main(String[] args) {
//多态向上转型
Employ e = new personnel();
e.setName("小强");
e.setId("sd0001");
e.setSalary(15000);
e.work();
System.out.println(e.getName()+"---"+e.getId()+"---"+e.getSalary());
System.out.println("-----------");
e = new manager("小明","sd0010",25000,10000);
//多态向下转型
manager m = (manager)e;
m.work();
System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getBonus());
}
}
-----------------------------------------------------------------------------------------
结果:
按照需求写代码
小强---sd0001---15000
-----------
与客户谈需求
小明---sd0010---25000---10000
一个类如果没有抽象方法,定义为为抽象类的意义是不让创建对象。
abstrace 不能和哪些关键子共存
private 冲突 (方法重写冲突)
final 冲突 (方法重写冲突)
static 无意义 (抽象方法无方法体,访问无意义)
接口:
接口的特点:
接口用关键字interface表示
interface 接口名 { }
类实现接口用implements表示
class 类名 implements 接口名 { }
接口按照多态的方式实例化
接口的子类
可以是抽象类,但是意义不大。
可以是具体类。要重写接口中的所有抽象方法。
由此可见
具体类多态(几乎没有)
抽象类多态(常用)
接口多态(最常用)
接口成员特点
成员变量:只能是常量,并且是静态的。
默认修饰符:public static final 建议:自己给出
构造方法:接口没有构造方法;因为接口主要是扩展功能,而没有具体存在
成员方法:只能是抽象方法。
默认修饰费用: public abstract
所有的类都默认继承自一个类:Object。
类 Object 是类层次结构的跟类。每个类都使用 Object 作为超类。
类与类:
继承关系,只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。
接口与接口:
继承关系,可以单继承,也可以多继承。
抽象类和接口的区别:
成员区别:
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以常量
成员方法:只可以抽象
关系区别:
类与类
继承,单继承
类与接口
实现,单继承,多继承
接口与接口
继承,单继承,多继承
设计理念区别
抽象类 被继承体现的是:“is a”的关系。抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:“like a”的关系。接口中定义的是该继承体系的扩展功能。
interface Jumpping{
public abstract void jump();
}
abstract class Anmial{
//姓名
private String name;
//年龄
private int age;
//无参构造
public Anmial() {
}
//带参构造
public Anmial(String name,int age) {
this.name=name;
this.age=age;
}
//getXxx()/setXxx()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//吃饭,抽象方法
public abstract void eat();
//睡觉
public void sleep() {
System.out.println("睡觉!");
}
}
class Cat extends Anmial {
//无参构造
public Cat() {
}
//带参构造
public Cat(String name,int age) {
super(name,age);
}
//重写方法
public void eat() {
System.out.println("猫吃鱼");
}
}
class Dog extends Anmial{
//无参构造
public Dog() {
}
//带参构造
public Dog(String name,int age) {
super(name,age);
}
//重写方法
public void eat() {
System.out.println("狗吃肉");
}
}
class JumpCat extends Cat implements Jumpping{
//无参构造
public JumpCat() {
}
//带参构造
public JumpCat(String name,int age) {
super(name,age);
}
//接口
public void jump() {
System.out.println("跳高猫");
}
}
class JumpDog extends Dog implements Jumpping{
//无参构造
public JumpDog() {
}
//带参构造
public JumpDog(String name,int age) {
super(name,age);
}
//接口
public void jump() {
System.out.println("跳高狗");
}
}
public class JumpDogCat {
public static void main(String[] args) {
JumpCat c = new JumpCat();
c.setName("Tom");
c.setAge(4);
System.out.println(c.getName()+"---"+c.getAge());
c.eat();
c.sleep();
c.jump();
System.out.println("---------");
JumpDog d = new JumpDog("旺财",5);
System.out.println(d.getName()+"---"+d.getAge());
d.eat();
d.sleep();
d.jump();
}
}
------------------------------------------------------------------------------------
结果:
Tom---4
猫吃鱼
睡觉!
跳高猫
---------
旺财---5
狗吃肉
睡觉!
跳高狗
//接口,说英语
interface SpeakEnglish{
public abstract void say();
}
//抽象类,人
abstract class Person{
//姓名
private String name;
//年龄
private int age;
//无参构造
public Person() {
}
//带参构造
public Person(String name,int age) {
this.name = name;
this.age = age;
}
//getXxx()/setXxx()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//吃饭,抽象方法
public abstract void eat();
//睡觉
public void sleep() {
System.out.println("睡觉");
}
}
//抽象类,运动员
abstract class Athlete extends Person{
//无参构造
public Athlete() {
}
//带参构造
public Athlete(String name,int age) {
super(name,age);
}
//抽象方法,学习
public abstract void study();
}
//抽象类,教练
abstract class Coach extends Person{
//无参构造
public Coach() {
}
//带参构造
public Coach(String name,int age) {
super(name,age);
}
//抽象方法,教
public abstract void teach();
}
//具体类,乒乓球运动员
class TableAthlete extends Athlete implements SpeakEnglish{
//无参构造
public TableAthlete() {
}
//带参构造
public TableAthlete(String name,int age) {
super(name,age);
}
//接口,说英语
public void say() {
System.out.println("说口语!");
}
//继承吃饭
public void eat() {
System.out.println("乒乓球运动员吃饭!");
}
//继承学习
public void study(){
System.out.println("乒乓球运动员学习");
}
}
//具体类,篮球运动员
class BasketballAthlete extends Athlete {
//无参构造
public BasketballAthlete() {
}
//带参构造
public BasketballAthlete(String name,int age) {
super(name,age);
}
//继承吃饭
public void eat() {
System.out.println("篮球球运动员吃饭!");
}
//继承学习
public void study(){
System.out.println("篮球运动员学习");
}
}
//具体类,乒乓球教练
class TableCoach extends Coach implements SpeakEnglish{
//无参构造
public TableCoach() {
}
//带参构造
public TableCoach(String name,int age) {
super(name,age);
}
//继承吃饭
public void eat() {
System.out.println("乒乓球教练吃饭!");
}
//继承教
public void teach() {
System.out.println("乒乓球教练教!");
}
//接口
public void say() {
System.out.println("乒乓球教练说英语");
}
}
//具体类,篮球教练
class BasketballCoach extends Coach{
//无参构造
public BasketballCoach() {
}
//带参构造
public BasketballCoach(String name,int age) {
super(name,age);
}
//继承吃饭
public void eat() {
System.out.println("乒乓球教练吃饭!");
}
//继承教
public void teach() {
System.out.println("乒乓球教练教!");
}
}
public class Athletecoach {
public static void main(String[] args) {
TableAthlete ta = new TableAthlete();
ta.setName("李华");
ta.setAge(20);
System.out.println(ta.getName()+"---"+ta.getAge());
ta.eat();
ta.say();
ta.study();
ta.sleep();
System.out.println("---------");
BasketballAthlete ba = new BasketballAthlete("张三",19);
System.out.println(ba.getName()+"---"+ba.getAge());
ba.eat();
ba.study();
ba.sleep();
System.out.println("--------");
TableCoach tc = new TableCoach();
tc.setName("刘备");
tc.setAge(30);
System.out.println(tc.getName()+"---"+tc.getAge());
tc.eat();
tc.say();
tc.teach();
tc.sleep();
System.out.println("---------");
}
}
---------------------------------------------------------------------------------
结果:
李华---20
乒乓球运动员吃饭!
说口语!
乒乓球运动员学习
睡觉
---------
张三---19
篮球球运动员吃饭!
篮球运动员学习
睡觉
--------
刘备---30
乒乓球教练吃饭!
乒乓球教练说英语
乒乓球教练教!
睡觉
---------