* 多态概述
*事物存在的多种形态
* 多态前提
要有继承关系
要有方法重写
要有父类引用指向子类对象
class Test{
public static void main(String[] args){
Cat c = new Cat();
c.eat();
System.out.println(c.num);
Animal a = new Cat(); //父类引用指向子类对象, 就是向上转型
a.eat();
//成员方法:编译看左边(父类), 运行看右边(子类)[也叫动态绑定]
//静态方法:编译看左边, 运行看左边
System.out.println(a.num); //成员变量:编译看左边(父类), 运行看左边(父类)
Cat sm = (Cat)a; //一定先有向上转型,才有这个向下转型
sm.test();
}
}
class Animal {
int num = 10; //成员变量
public void eat(){
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
int num = 20;
public void eat() {
System.out.println("猫吃鱼");
}
public void test() {
System.out.println("test");
}
}
结果:
"猫吃鱼"
20
"猫吃鱼"
10
"test"
# 抽象类不能直接实列,可以通过子类进行示例(父类引用,指向子类对象)
* 抽象类的子类,要不是抽象类,要不就直接重写抽象类中的所有方法
abstract class test{
public abstract void eat() {
System.out.println("helloworld !!!");
}
}
* abstract 不能和其它关键字并用: static , final , private
* 接口的定义
interface 接口名 {}
* 类实现接口用implements 表示
class 类名 implements 接口名 {}
* 接口不能实列化: 可以通过多态来实例化
* 接口成员特点
* 成员变量:只能是常量,并且是静态的并公共的
默认修饰符:public static final
* 构造方法:接口没有构造方法
* 成员方法:只能是抽象方法
默认修饰符:pulic abstract
* 类与类,类与接口,接口与接口的关系
* 类与类:
继承关系,只能但继承,可以多层继承
* 类与接口:
实现关系,可以单实现,也可以多实现
并且还可以再继承一个类的同时实现多个接口
* 接口与接口
继承关系,可以单继承,也可以多继承
# 面向对象(package关键字的概述及作用
* A:为什么要有包
* 将字节码(.class)进行分类存放
* 包其实就是文件夹
* B:包的概述
举例:
学生:增加,删除,修改,查询
老师:增加,删除,修改,查询
方案1:按照功能分
com.heima.add
AddStudent
AddTeacher
com.heima.delete
DeleteStudent
DeleteTeacher
com.heima.update
UpdateStudent
UpdateTeacher
com.heima.find
FindStudent
FindTeacher
方案2:按照模块分
com.heima.teacher
AddTeacher
DeleteTeacher
UpdateTeacher
FindTeacher
com.heima.student
AddStudent
DeleteStudent
UpdateStudent
FindStudent
* A:定义包的格式
* package 包名;
* 多级包用.分开即可
* B:定义包的注意事项
* A:package语句必须是程序的第一条可执行的代码
* B:package语句在一个java文件中只能有一个
* C:如果没有package,默认表示无包名
* A:如何编译运行带包的类
* a:javac编译的时候带上-d即可
* javac -d . HelloWorld.java
* b:通过java命令执行。
* java 包名.HellWord
* 不同包下类之间的访问: 先编译,在调用的时候需要加包名
* 为什么要有import
* 其实就是让有包的类对调用者可见,不用写全类名了
* B:导包格式
* import 包名;
* 注意:
* 这种方式导入是到类的名称。
* 虽然可以最后写*,但是不建议。
* C:package,import,class有没有顺序关系
* A:修饰符:
* 权限修饰符:private,默认的,protected,public
* 状态修饰符:static,final
* 抽象修饰符:abstract
* B:类:
* 权限修饰符:默认修饰符,public
* 状态修饰符:final
* 抽象修饰符:abstract
* 用的最多的就是:public
* C:成员变量:
* 权限修饰符:private,默认的,protected,public
* 状态修饰符:static,final
* 用的最多的就是:private
* D:构造方法:
* 权限修饰符:private,默认的,protected,public
* 用的最多的就是:public
* E:成员方法:
* 权限修饰符:private,默认的,protected,public
* 状态修饰符:static,final
* 抽象修饰符:abstract
* 用的最多的就是:public
* F:除此以外的组合规则:
* 成员变量:public static final
* 成员方法:
* public static
* public abstract
* public final
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
* B:内部类访问特点
* a:内部类可以直接访问外部类的成员,包括私有。
* b:外部类要访问内部类的成员,必须创建对象。
* 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(?);
System.out.println(??);
System.out.println(???);
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
* 局部内部类访问局部变量必须用final修饰
* 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用。
但是jdk1.8取消了这个事情。
* A:匿名内部类
* 就是内部类的简化写法。
* B:前提:存在一个类或者接口
* 这里的类可以是具体类也可以是抽象类。
* C:格式:
new 类名或者接口名(){
重写方法;
}
* D:本质是什么呢?
* 是一个继承了该类或者实现了该接口的子类匿名对象。
//这里写抽象类,接口都行
abstract class Person {
public abstract void show();
}
class PersonDemo {
public void method(Person p) {
p.show();
}
}
class PersonTest {
public static void main(String[] args) {
//如何调用PersonDemo中的method方法呢?
PersonDemo pd = new PersonDemo ();
}
}