package
就是文件夹
导包
相同包内可以直接访问,不同包下的类需要导包才能互相访问
格式:import 包名.类名;
一个类需要用到不同类,而这两个类名是一样的,那么默认只能导入一个类,另一个要带包名访问。(使用全类名创建对象:包名.类名)
package com. itheima.c; import com . ithe ima.a . Student; public class Test { public static void main(String[] args) { Student stu1 = new Student(); stul.eat() ; //使用全类名创建对象:包名+类名 com. itheima.b.Student stu2 = new com. itheima.b. Student(); stu2. sleep();| } }
抽象类
public static void main(String[] args) {
}
class Animal {
public void eat(){
System.out.println("????"); //共性方法eat抽取后在父类描述不清
}
}
class Cat {
public void eat(){
System.out.printLn("猫吃鱼");
}
}
class Dog {
public void eat(){
System.out.printLn("狗吃肉");
}
}
对上述代码修改提取抽象方法
public static void main(String[] args) {
}
abstract class Animal { //抽象类
public abstract void eat() ; /*{
System.out.println("????"); 此部分舍去,将方法抽象化
} */
}
class Cat extends Animal {
@Override//重写方法
public void eat(){
System.out.printLn("猫吃鱼");
}
}
class Dog extends Animal{
@Override//重写方法
public void eat(){
System.out.printLn("狗吃肉");
}
}
抽象类的注意事项
-
抽象类不能**实例化**
如果允许创建对象,就可以调用内部没有方法体的抽象方法了
public static void main(String[] args) { Fu f = new Fu();//报错 f. show();//错误示范,抽象方法不能被调用 } abstract class Fu { public abstract void show();| I}
-
抽象类存在构造方法
交给子类,通过super进行访问
abstract class Fu { public Fu(){ } public abstract void show(); } class Zi extends Fu { public Zi(){ super(); } @0verride public void show() { } }
-
抽象类中可以存在普通方法
抽象类中可以存在普通方法(让子类继承使用)
-
抽象类的子类1).要么重写抽象类中的所有抽象方法
2).要么是抽象类
abstract class A { public abstract void showA() ; } abstract class B extends A { @override public void showA() { //多个抽象类的多级继承,不断向下继承新规则 } public abstract void showB(); } cLass C extends B { @override public void showB() { }
-
abstract与final、private、static冲突
接口(干爹)
介绍
对规则的声明,对行为的抽象。其子类根据其抽象方法重写方法,实现了接口对其的约束
如果发现一个类,所有的组成,都是抽象方法,将其设定为接口
定义
格式:interface 接口名 {内部只能声明抽象方法}
接口不允许实例化(不能new对象)
接口和类之间是实现关系,通过implements 关键字完成
class 类名 implements 接口名 { }
实现类:1)重写抽象方法
2)将实现类变为抽象类
3)可实现多个接口,不存在方法重名问题
public static void main(String[] args) { //创建实现类对象 InterImpL ii = new InterImpl(); ii. method(); ii. show(); } } interface Inter { public abstract void show(); public abstract void method(); } class InterImpL implements Inter { //实现Inter接口,InterImpl 是实现类(接口子类) @override //重写方法 public void show() { System. out. printLn("show..."); } @Override //重写方法 public void method() { System. out . printLn( "method..."); } }
成员特点
只能定义常量(int char…),因为系统默认加入三个关键字public(跨包访问) static(类名.调用) final(不可更改)
只能是抽象方法(void 方法名()),因为系统默认加入三个关键字public(跨包访问) abstract(没写自动加)
接口和类之间的各种关系:
- 类和类之间:继承关系,只支持单继承,不支持多继承,但是可以多层继承
- 类和接口之间:实现关系,可以单实现, 也可以多实现,甚至可以在继承-一个类的同时,实现多个接口
- 接口和接口之间:继承关系,可以单继承,也可以多继承
抽象类和接口的对比
抽象类
任然是对某一个事物进行描述,对事物的某些特征抽象化
接口
对行为抽象,为程序制定规则,使代码更加规范(写业务之前,先制定业务接口)
多态
同一个行为(方法)具有多个不同表现形式或形态的能力
多态前提
- 有继承或实现关系
- 有方法重写
- 有父类引用指向子类对象
-
对象多态
好处:可将方法的形参定义为父类类型,这个方法就可以接受任意子类对象
public static void main(String[] args) { Animal a1 = new Dog(); //父类引用指向子类对象 Animal a2 = new Cat(); //此种对象创建方式叫做对象多态 //useDog(new Dog()); //useCat(new Cat()); useAnimal(new Dog()); //可接收子类对象 useAnimal(new Cat()); } abstract class Animal { public abstract void eat() ; } /*public static void useDog(Dog d){ } public static void useCat(Cat c){ } 将此串代码优化成一个方法可以接收两个对象*/ public static void useAnimal(Animal a){ //将参数类型指定为父类类型 } //Animal a=new Dog(); //Animal a=new Cat(); class Cat extends Animal { @Override//重写方法 public void eat(){ System.out.printLn("猫吃鱼"); } } class Dog extends Animal{ @Override//重写方法 public void eat(){ System.out.printLn("狗吃肉"); } }
-
行为多态
好处:同一个方法,具有多种不同表现形式或形态的能力
public static void main(String[] args) { Animal a1 = new Dog(); //父类引用指向子类对象 Animal a2 = new Cat(); //此种对象创建方式叫做对象多态 useAnimal(new Dog()); //可接收子类对象 输出"狗吃肉” useAnimal(new Cat()); //输出"猫吃鱼" } abstract class Animal { public abstract void eat() ; } public static void useAnimal(Animal a){ //将参数类型指定为父类类型 a.eat(); } class Cat extends Animal { @Override//重写方法 public void eat(){ System.out.printLn("猫吃鱼"); } } class Dog extends Animal{ @Override//重写方法 public void eat(){ System.out.printLn("狗吃肉"); } }
多态中成员访问特点
-
成员变量:编译看左边(父类),运行看左边(父类)
-
成员方法:编译看左边(父类),运行看左边(子类)
在编译时检查父类中是否有这个方法;若有则运行子类方法
多态创建对象,调用静态成员
静态的成员,推荐类名进行调用
对象名调用:在字节码编译后,变为类名.对象名.调用
public static void main(String[] args) { Fu f = new Zi(); //以多态的形式创建子类对象 System.out.println(f.num); //使用父类中的10 f.show(); //调用成员方法运行子类show() f.print(); //对象名调用静态print方法,走父类逻辑 Inter i=new InterImpl(); //接口实现的多态,走子类方法逻辑(接口方法抽象) } interface Inter{ void method(); } class TnterImpl implements Inter{ @Override public void method( ) { System. out. println("method..."); } } class Fu { int num = 10; public void show() { System. out. printLn("Fu...show"); } public static void print(){ //静态方法 System. out. printLn("Fu...print"); } } class Zi extends FU { int num = 20; @override public void show() { System. out . printLn("Zi... show" ); } public static void print(){ //静态方法 System. out. printLn("Zi...print"); } }
-
多态的好处和弊端
-
多态的好处:提高了程序的扩展性
对象多态:将方法的形参定义为父类类型,这个方法可以接收该父类的任意子类对象
行为多态:同-个行为,具有多个不同表现形式或形态的能力
-
多态的弊端:不能使用子类的特有成员(除非使用多态转型),父类中没有
多态中的转型
向上转型
从子到父(父类引用指向子类对象) Fu f = new Zi();
向下转型
从父到子(将父类引用所指向的对象,转交给子类类型(回归到子类)) Zi z =(Zi) f;
在引用数据类型的强转中,[实际类型]和[目标类型]不匹配,就会出现此异常
解决方法:instanceof 判断左边的引用,是否是右边的数据类型