一、抽象类注意事项
-
问题:
一个类,没有抽象方法,可不可以将这个类定义为抽象类呢? 意义是什么?
可以定位抽象类,意义:就是为了这个类不能够实例化!一般情况:如果一个类中,没由抽象方法,将它定义为抽象类
它的实例化: 可以通过它里面的静态功能,静态功能的返回值类型是当前类本身!
后期:Calendar:日历类 java.util.Calendar;Calendar:抽象类 public static Calendar getInstantce(){ .... .... .... return new GregorianCalendar() ; Calendar的子类 }
-
抽象 的关键字:
abstract不能和哪些关键字使用(冲突)abstract可以修饰类,才是这个类不能实例化了,这个类叫抽象类
abstract可以修饰方法----抽象方法:没有方法体
和private关键字不能一块使用:被private修饰的只能在本类中访问,外界类中的成员不能访问!
和static关键字冲突:如果加了静态,子类要重写父类的方法,这种访问方式:
多态:Fu f = new Zi() ;f.方法名() ;
静态的方式—>随着类的加载而加载: 类名.方法名();
和final关键字冲突:被final修饰的方法不能被重写,而abstract抽象方法,要强制子类必须重写,否则子类报错,出现冲突了!abstract:和默认修饰符 abstract 返回值类型 方法名(形参列表) ;
和public可以使用
和protected:
限定的是子类: 在同一个包下/或者在不同包下 都可以访问
举例:
abstract class Animal{
//非抽象方法
public void show(){
System.out.println("show Animal");
}
// protected abstract void eat() ;
public abstract void eat() ;
//abstract void eat() ;
//不行的
//private abstract void eat() ; //和private冲突
//public static abstract void eat() ;//和static关键字冲突
// public final abstract void eat() ;//和final关键字冲突
}
class Cat extends Animal{
public void show(){
System.out.println("show Cat");
}
@Override
public void eat() {
}
}
//测试类
public class AbstractDemo {
public static void main(String[] args) {
Animal a = new Cat() ;
a.show();
}
}
二、方法重写注意事项
方法重写的注意事项:
子类继承父类,要重写父类的功能的时候,必须要保证子类的方法的访问权限足够大,要么
就父类的权限保持一致即可!
举例:
//父类
class Fu{
/* public void show(){
System.out.println("show Fu");
}*/
void show(){
System.out.println("show Fu");
}
}
class Zi extends Fu{
//不能够访问
/* void show(){
System.out.println("show Zi");
}*/
public void show() {
System.out.println("show Zi");
}
}
//测试类
public class OverrideDemo {
public static void main(String[] args) {
Fu fu = new Zi() ;
fu.show() ;
}
}
三、接口
-
什么是接口?
接口是比抽象类还抽象的事物,它体现的一种 “扩展性”— 事物的额外功能!
如果一些具体事物能够将额外功能实现了,那么这些具体事物就应该具备这些功能了!
接口:体现的是一种 "like a"的关系
跳高猫—>类似猫 -
定义格式:
interface 接口名{ //接口名要见名知意---符号"标识符的规则" }
-
接口中的方法:只能是抽象方法
-
接口特点:不能实例化:不能new
将接口的子类称为"子实现类"
可以是抽象类, 一定会有抽象类的具体的子类,否则没有意义!
也可以是具体类 : 通过具体类实例化接口名 对象名 = new 子实现类名() ;
子实现类和接口之间的关系:实现关系 :implements
class 子实现类名 implements 接口名{ }
举例:
//定义一个跳高的接口
interface Jump{
public abstract String jump() ;
}
//猫类
//abstract class Cat implements Jump { //类与接口的关系;实现关系
class Cat implements Jump {
//类与接口的关系;实现关系
public void eat(){
System.out.println("猫吃鱼");
}
public void catchMouse(){
System.out.println("猫抓老鼠...");
}
@Override
public String jump() {
return "猫可以跳高了" ;
}
}
//测试类
public class InterfaceDemo {
public static void main(String[] args) {
//Jump jump = new Jump() ;//不能实例化
// Jump jump = new Cat() ; //不能实例化 :Cat是抽象类
//Cat如果是具体类
Jump jump = new Cat() ; 接口多态: (使用的 最多的) 向上转型
String str = jump.jump();// 使用的 接口(就是一个abstracct)的
System.out.println(str);
// jump.eat() ;
Cat c = (Cat)jump ;//向下转型
c.eat();
c.catchMouse() ;
}
}
四、接口中的成员特点
成员变量:只能是常量:存在默认修饰符:public static final … :可以省略不写
构造方法:无
成员方法:只能是抽象方法:存在默认修饰符:public abstract :可以省略不写
开发中,定义了一个接口
子实现类名都是在接口名的后面加上Impl
举例:
//定义一个接口
interface Inter{
/* public Inter(){
}*/
//成员变量
int num = 100 ;
final int num2 = 200 ;
void show() ;
//public void method(){}
public abstract void method() ;
}
//子实现类
class InterImpl implements Inter{
@Override
public void show() {
System.out.println("show InterImpl");
}
@Override
public void method() {
System.out.println("method InterImpl");
}
}
//测试类
public class InterfaceDemo2 {
public static void main(String[] args) {
//接口多态的形式
Inter i = new InterImpl() ;
System.out.println(i.num);
// i.num = 200 ; //也是常量 :已经被final修饰(没有明确显示)
//i.num2 = 300 ;//num2已经final修饰了
System.out.println(Inter.num); //接口名.变量--->变量: static修饰
System.out.println(Inter.num2)