Java day8
来源:互联网 发布:判断微信浏览器 js 编辑:程序博客网 时间:2024/06/15 19:33
一、多态
1.多态:一个事物在不同时刻体现出来的不同状态。
例:Animal a = new Cat();
2.对于多态的三个前提条件:
(1)条件1:必须有继承关系(如果没有继承关系,谈不上多态)
(2)条件2:必须有方法重写
子类出现了父类一样的方法声明。
(3)有父类引用指向子类对象:向上转型
Fu f= new Zi();
注:多态的三个条件缺一不可。
3.多态的成员访问特点:
成员变量:
编译看左边,运行看左边
成员方法(非静态的成员方法):
编译看左,运行看右;由于存在方法重写,所以就运行最终的就是子类的成员方法
静态成员方法:(静态方法算不上方法重写,静态直接跟类有关系)
编译看左,运行看左
构造方法:还是对象进行初始化,由于是一种继承关系,还是分层初始化。
分层初始化:父类先初始化,然后子类初始化。
步骤:
在测试类中创建父类的对象:多态的形式
由父类引用指向子类对象:向上转型
Fu f = new Zi();
访问成变量
调用成员方法:show()
f.show();
例:创建对象
多态版(实际开发中:多态使用最广泛:接口多态是经常使用的!)
Animal a = new Cat() ;
a.eat();
a.sleep();
a = new Dog();
a.eat();
a.sleep();
4. 多态的好处(特点):
(1)提高代码的维护性(由继承保证)
(2)提高代码的扩展性(由多态保证)
注:java的开发原则:低耦合,高内聚。
例:
父类为:Animal 子类为:猫类 狗类 猪类
猫类 狗类 猪类都有自已的功能
再写一个动物的工具类
先将将类中无参构造私有化:目的是为了不让外界创建对象。
形式参数为一个父类
在测试类实现功能;
1. 可以直接创建对象调用
Cat c1 = new Cat();
c1.eat();
2. 优化改进:将猫的吃和睡的方法封装成独立的功能
public static void useDog(Dog d){
d.eat();
d.sleep() ;
在测试类调用
Dog d1 = new Dog();
Dog d2 = new Dog();
Dog d3 = new Dog();
调用狗的功能
useDog(d1);
useDog(d2);
useDog(d3);
3.最终版代码
先创建AnimalTool对象
AnimalTool at = newAnimalTool();
形式参数:Animal a = new Cat();
a.useAnimal(c1);
at.useAnimal(c2);
at.useAnimal(c3);
5. 多态的弊端:
不能访问子类的特有功能。
多态的弊端是不能访问子类的特有功能:如何解决?
注:异常:OOM异常:严重:OutOfMemory:内存溢出
解决方案:
(1)创建子类的具体对象,来访问自己的特有功能;虽然可以解决多态的弊端,但是从内存角度考虑,需要创建子类对象,那么必须在堆内存开辟空间。
弊端: 耗费内存,浪费空间。
(2)既然多态的第三个前提条件:父类引用指向子类对象,那么可不可以将子类的引用指向父类对象呢?
可以的:向下转型:将父类的引用强制转换为子类的引用:前提必须有父类的引用存在。
注:向下转型必须依赖于向上转型。
例:在测试中
父类引用指向子类对象
Animal3 a = new Cat3(); //向上转型
a.show();
此处不能访问子类特有功能:playGame()
a.playGame();
访问方案:
1.创建子类具体对象
Cat c = new Cat();
c.playGame() ;
2.父类的引用强制转换为子类的引用。
Cat c = (Cat) a ;
c.playGame() ;
注:一般情况下:向下转型使用不当会造成一个异常:
Throwable:
error:严重问题
Exception:编译时期异常:
运行时期异常:RuntimeException
运行时期异常:
ClassCastException:类转换异常:…… cannot be cast to ……
例:在测试类中
内存是狗
Animal a = new Dog() ;
//向下转型:还原成狗
Dog d = (Dog)a ;
//内存是猫
a = new Cat() ;
//还原成猫
Cat c = (Cat) a ;
//编译通过了
Dog dd = (Dog)a ; //不能将内存猫转换为狗
二、抽象类
1.抽象类的概念:每一个动物的吃和睡的功能不一样,不应该把动物类定义为
一个具体类,而是给出一个声明(abstract)。
注:当一个类中如果有抽象功能(抽象方法)的时候,那么这个类一定要定义为抽象类。
问题:一个抽象类中可以有非抽象方法吗?
一个抽象类中可以抽象,也可以有非抽象的(判断题)
抽象类不能实例化:抽象类不能创建对象
一个抽象类如何进行实例化:
通过抽象类多态形式:父类的引用指向子类对象,通过子类进行初始化。
2.抽象类的子类的特点:
(1)抽象类的子类是抽象类,那么没有意义。子类一定是具体类。
最终使用的就是通过子类进行对象初始化的,如果子类都被抽象修饰了,那么也不能创建对象,所以没意义。
抽象类多态:
抽象类的类名 对象名= new 子类名() ;
强制子类必须重写当前抽象的父类中所有的抽象方法,还可以提高代码的维护性(里面继承关系保证)。
抽象方法:没有方法体的一个方法。
public abstract void eat() ;
注:异常:Cannot instantiatethe type Animal:抽象类不能实例化:instaceof
问题:
一个类中如果没有抽象方法,那么这个类可不可以定义为一个抽象类呢?
可以!为什么?不能让其创建对象。
3.abstract不能和哪些关键字共同使用?
private和abstract不能共同使用
final和abstract不能共同使用
static和abstract不能共同使用
注:实际开发中:public 公共访问权限。
4.抽象类的成员特点
成员变量:
可以是变量也可以是自定义常量
构造方法:
抽象类可以有构造方法:包括有参构造和无参构造
作用:通过抽象类多态的形式:让子类进行数据的初始化
成员方法:
可以有抽象方法,也可以有非抽象方法
5.抽象类的成员方法特性:
抽象方法:强制子类必须要做到一件事情:方法重写(覆盖)。
非抽象方法:由继承保证可以去提高代码的复用性。
三、 接口
1.接口的概念:
接口体现的是一种:扩展功能:比如:猫可以跳高(并不是所有的猫都具有跳高功能)。
如何表示接口:
interface接口名{
}
接口里面的方法可以是非抽象方法吗?
不可以,只能是抽象方法
接口中不能有构造方法
2.接口的特点:不能实例化(不能直接创建对象)
接口如何实例化:
接口的子实现类:
(1)接口的子实现类是抽象类,没有意义,子类都不能创建对象了;实际开发中用的就是子类的对象进行初始化。
(2)接口的子实现类是非抽象类
接口的实例化:就是通过子实现类对数据进行初始化
接口的子实现类和接口的关系:implements:
格式:
class子实现类名 implments(实现) 接口名{
}
3.接口成员的特点:
成员变量:
只能是常量:存下默认修饰符:public static final (永远建议自己给出默认修饰符)
构造方法:
接口是没有构造方法的
成员方法:
接口中的成员方法默认修饰符:public abstract(永远建议自己给出默认修饰符)
4.类与类的关系:
继承关系:extends,java中只支持单继承,不支持多继承,但是可以多层继承。
类与接口的关系
实现关系:implements,并且,一个类在继承另一个类的同时,可以实现多个接口
(class 子实现类名 enxtends Object implements 接口名1,接口名2…)
接口与接口的关系
继承关系:extends,可以支持单继承,也可以多继承。
5.接口和抽象类的区别?
(1)成员的区别:
成员变量:
抽象类:成员变量可以是常量,也可以是变量
接口:成员变量只能是一常量:存在默认修饰符:public static final
构造方法:
抽象类:可以有无参构造,有参构造方法
作用:通过子类进行数据初始化(通过子类创建对象)
接口:没有构造方法的
成员方法的区别:
抽象类:可以有抽象方法,也可以有非抽象方法
接口:只能是抽象方法:存在默认修饰符:public abstract
(2)关系的区别:
类与类的关系:
继承关系:extends,java中只支持单继承,不支持多继承,但是可以多层继承。
类与接口的关系:
实现关系:implements,并且,一个类在继承另一个类的同时,可以实现多个接口。
(class 子实现类名 enxtends Object implements 接口名1,接口名2…)
接口与接口的关系
继承关系:extends,可以支持单继承,也可以多继承。
(3)设计理念的区别:
抽象类:
体现的是一种"is a"的关系,存在继承关系!(抽象类多态)。
接口:
体现的是一种"like a"的关系,由于接口的一种扩展功能。
举例:
假如我们在开发一个系统时需要对员工类进行设计,程序员包含3个属性:姓名、工号(String)以及工资。(salary)
经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。(bonus)
请使用继承的思想设计出程序员类和经理类。要求类中提供必要的方法进行属性访问。
分析:
具体到抽象
程序员类:Programmer
成员变量:姓名,工号,工资
构造:有参,无参
成员方法:
setXXX()/getXXX(),work()
经理类:Manager
成员变量:姓名,工号,工资
额外的属性:奖金
构造:有参,无参
成员方法:
setXXX()/getXXX(),work()
抽取共性内容:独立的类:Employee(抽象类)
普通员工和经理做的事情不一样,work();抽象方法
测试类:
代码的实现:从抽象到具体
员工类(抽象类)
普通员工(程序员类)
经理类
部分经理和程序员会游泳:
接口: Swim
游泳的抽象功能
package day8;
public abstract class Employee {
private String name ;
private String empId ;
private int salary ;
public Employee() {//Alt+Shift+s+c
super();
}
public Employee(String name, String empId, int salary) {//Alt+Shift+s+o
super();
this.name = name;
this.empId = empId;
this.salary = salary;
}
public String getName() {//Alt+Shift+s+r
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public abstract void work() ;//抽象的功能
}
package day8;
public class ProgrammerSwim extends Programmer implements Swimming {
public ProgrammerSwim() {
super();
// TODO自动生成的构造函数存根
}
public ProgrammerSwim(String name, String empId, int salary) {
super(name, empId, salary);
// TODO自动生成的构造函数存根
}
@Override
public void swim() {
// TODO自动生成的方法存根
System.out.println("程序员会游泳!");
}
}
package day8;
public class Manager extends Employee {
//奖金属性
private int bonus;
public Manager() {
super();
// TODO自动生成的构造函数存根
}
public Manager(String name, String empId, int salary,int bonus) {
super(name, empId, salary);
// TODO自动生成的构造函数存根
this.bonus=bonus;
}
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
@Override
public void work() {
// TODO自动生成的方法存根
System.out.println("经理类和客户谈需求!");
}
}
package day8;
//游泳接口
public interface Swimming {
//抽象功能
public abstract void swim();
}
package day8;
public class ProgrammerSwim extends Programmer implements Swimming {
public ProgrammerSwim() {
super();
// TODO自动生成的构造函数存根
}
public ProgrammerSwim(String name, String empId, int salary) {
super(name, empId, salary);
// TODO自动生成的构造函数存根
}
@Override
public void swim() {
// TODO自动生成的方法存根
System.out.println("程序员会游泳!");
}
}
package day8;
public class ManagerSwim extends Manager implements Swimming {
public ManagerSwim() {
super();
// TODO自动生成的构造函数存根
}
public ManagerSwim(String name, String empId, int salary, int bonus) {
super(name, empId, salary, bonus);
// TODO自动生成的构造函数存根
}
@Override
public void swim() {
// TODO自动生成的方法存根
System.out.println("经理会游泳!");
}
}
package day8;
public class Work {
public static void main(String[] args){
//测试程序员类
Employee e = new Programmer();
e.setName("Tom");
e.setEmpId("abc123");
e.setSalary(10000) ;
System.out.println(e.getName()+" "+e.getEmpId()+" "+e.getSalary());
e.work();
System.out.println("----------------------------");
//方式2:构造方法进行赋值
e= new Programmer("Ammy","abc1235",10000) ;
System.out.println(e.getName()+" "+e.getEmpId()+" "+e.getSalary());
e.work();
System.out.println("----------------------------");
//测试经理类
Employee e1 = new Manager("Jone", "abc12345", 20000, 5000);
//System.out.println(e.getName()+" "+e.getEmpId()+" "+e.getSalary()+" "+m.getBonus());无法解析m.getBonus()
System.out.println(e.getName()+" "+e.getEmpId()+" "+e.getSalary());
e1.work();
System.out.println("----------------------------");
//如果一个类有特有属性:
//创建经理类对象
Manager m = new Manager() ;
m.setName("Jone") ;
m.setEmpId("abc12345");
m.setSalary(20000);
m.setBonus(5000);
System.out.println(m.getName()+" "+m.getEmpId()+" "+m.getSalary()+" "+m.getBonus());
m.work();
System.out.println("----------------------------");
//实现接口的类是最具体的类,创建该类对象
//经理游泳
ManagerSwim ms = new ManagerSwim();
ms.setName("Jone") ;
ms.setEmpId("abc12345");
ms.setSalary(20000);
ms.setBonus(5000);
System.out.println(m.getName()+" "+m.getEmpId()+" "+m.getSalary()+" "+m.getBonus());
m.work();
ms.swim() ;
System.out.println("----------------------------");
//通过有参构造进行数据初始化
ms = new ManagerSwim("Tom","abc12345", 20000, 5000) ;
System.out.println(m.getName()+" "+m.getEmpId()+" "+m.getSalary()+" "+m.getBonus());
ms.work();
ms.swim() ;
}
}
- Java Day8
- java day8
- Java day8
- java学习笔记day8
- java学习day8
- 码神-day8-java
- day8
- DAY8
- Day8
- DAY8
- Day8
- day8
- Day8
- 传智播客-Java基础加强-day8
- JAVA视频笔记(day8)
- 黑马程序员---java基础之day8-9
- 安卓学习记录-java-day8
- 自学 java 笔记 day8(继承下)
- android 6.0运行时权限
- HDU 1024 Max Sum Plus Plus【DP+滚动数组】
- org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name
- 配置hadoop-1.2.1 eclipse开发环境 Run as hadoop
- Spring MVC 跨域
- Java day8
- 策略模式
- Java 常用工具类 Collections 源码分析
- OpenShift Origin v3.7 端口转发
- PAT 甲级 1129. Recommendation System (25)
- ubuntu(16.04) 系统相互在root下免密ssh
- android的传参
- PAT 甲级 1130. Infix Expression (25)
- 工作总结