类
基本意义
类是具有共同属性和行为的对象的模板,类定义了对象的属性和行为。
1.创建类
基本声明
[访问权限修饰符] [修饰符] class 类名 { 类体 }
1.修饰符
public,default,abstract,final
public表示任意位置都可以访问该类;
不写表示默认访问修饰符,即在同一个包中可以访问;
abstract是表示该类为一个抽象类,不能实例化该类,即不能使用Test3 test3 = new Test3();的方式获取Test3的实例。如果要使用它则需要找一个类继承该类;
final表示该类不能被子类继承,该类即为最终类,不可再被继承。
为什么不能用private和protected修饰外部类?
1、private:用private修饰外部类,表示该外部类不能被其他类访问,那么定义这个类就失去了意义,所以private只能修饰内部类。内部类的上一级是外部类,那么对应的有四种访问控制修饰符:本类(private),同包(default),父子类(protected),任何位置(public)。当一个内部类使用了private修饰后,只能在该类的外部类内部使用。
2、protected:受保护的类,如果一个类被protected修饰,外部类无法访问,那又如何继承(继承的前提是可以访问)。所以用protected也是没有意义的
2.类的名称
Java类的命名规范如下:
1、 项目名全部小写
2、 包名全部小写
3、 类名首字母大写,如果类名由多个单词组成,每个单词的首字母都要大写。
如:public class MyFirstClass{}
4、 变量名、方法名首字母小写,如果名称由多个单词组成,每个单词的首字母都要大写。
如:int index=0;
public void toString(){}
5、 常量名全部大写
如:public static final String GAME_COLOR=”RED”;
6、所有命名规则必须遵循以下规则:
1)、名称只能由字母、数字、下划线、$符号组成
2)、不能以数字开头
3)、名称不能使用JAVA中的关键字。
4)、坚决不允许出现中文及拼音命名。
3.类的继承
增强代码的重用性,提供一个父子关系的逻辑。
写法
public class Dog extends Animal{}//子类会继承父类的所有非私有方法和属性
方法的覆盖
两同: 方法名相同 / 形参列表相同
两小: 子类方法返回值类型应比父类方法返回值类型小或相等. / 子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等.
一大: 子类方法的访问权限应比父类方法的访问权限大或相等.
super 限定
如果需要在子类方法中调用父类被覆盖的实例方法.
则可以使用 super 限定来调用父类被覆盖的实例方法.
public void callOverrideMethod(){
super.fly();
}
4.抽象类
一般用作设计模板。
写法
public abstract class Animal {
public abstract void run();
}
使用
//继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。最终,必须有子类实现该父类的抽象方法,否则,从最初的父类到最终的子类都不能创建对象,失去意义。
public class Cat extends Animal {
public void run (){
System.out.println("小猫在墙头走~~~");
}
}
public class CatTest {
public static void main(String[] args) {
// 创建子类对象
Cat c = new Cat();
// 调用run方法
c.run();
}
}
输出结果:
小猫在墙头走~~~
特点
1.有抽象方法的类一定是抽象类,但是抽象类不一定有抽象方法
2.抽象类是不可以直接创建对象的,但是可以通过其子类来创建对象
3.抽象类中有构造方法,但是不可以用来创建对象,但是可以供子类初始化父类的成员变量
4.抽象类的子类如果是普通类,那么必须实现抽象类中的抽象方法
5.抽象类的子类如果是抽象类,那么就可以不用实现抽象类中的抽象方法
5.接口
接口是若干常量和抽象方法的集合 ,是对类的抽象,是一种规范。
写法
public interface SataHdd{}
特点
1.定义的变量默认都是public static final修饰的,并且需要给出初始值
2.方法默认都是public abstract 修饰的,,如果是 private,procted,那么就编译报错
3. 接口中没有构造方法,不能被实例化。
4.一个接口不实现另一个接口,但可以继承多个其他接口
5.接口中的方法默认不能有具体的实现(JDK1.8开始可以有默认的实现)
多态
面向接口编程
屏蔽子类之间的特异性,写出通用编程
接口和抽象类的区别
参数 | 抽象类 | 接口 |
---|---|---|
默认的方法实现 | 可以有默认的方法实现 | 完全抽象,根本不存在方法的实现 |
实现方式 | 子类用extends关键字来继承抽象类,如果子类不是抽象类的话,它需要实现父级抽象类中所有抽象方法,父类中非抽象方法可重写也可不重写 | 子类用implements去实现接口,需要实现接口中所有方法 |
构造器 | 抽象类可以有构造器(构造器不能用abstract修饰) | 接口不能有构造器 |
与正常Java类的区别 | 正常Java类可被实例化,抽象类不能被实例化,其他区别见上下文 | 接口和正常java类是不同的类型 |
访问修饰符 | 抽象方法可以用public、protected、default修饰 | 接口默认是public、不能用别的修饰符去修饰 |
main方法 | 抽象类中可以有main方法,可以运行它 | 接口中不能有main方法,因此不能运行它 |
多继承 | 抽象类可继承一个类和实现多个接口 | 接口只能继承一个或者多个接口 |
速度 | 抽象类比接口速度快 | 接口稍微慢点,因为它需要去寻找类中实现的它的方法 |
添加新方法 | 如果在抽象类中添加新非abstract的方法,可以直接添加,因为非abstract方法无需在子类中实现,如果是abstact方法,则需要改变子类的代码,也要实现这个方法 | 只要在接口中添加方法,实现它的类就要改变,去实现这个新添加的方法 |
相同点:
(1)都不能被实例化
(2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点:
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
(5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。
设计层面上的区别
a. 抽象类是对一种事务的抽象,是对整个类进行抽象,包括属性,行为(方法)。接口是对行为(行为)的抽象。如果一个类继承或实现了某个抽象类,那么一定是抽象类的种类(拥有同一种属性或行为的类)。
b. 设计层面不同,抽象类作为很多子类的父类,是一种模板设计,而接口是一种规范,它是一种辐射式设计,也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象方法中添加实现,子类可以不用变更,
而对于接口不行,如果接口进行了变更,那么实现它的类都需要做变更。
接口和抽象类分别在什么时候使用
a. 如果拥有一些方法,并想让他们中的一些有默认的具体实现,请选择抽象类
b. 如果想实现多重继承,那么请使用接口,由于java不支持多继承,子类不能继承多个类,但一个类可以实现多个接口,因此可以使用接口来解决。
c. 如果基本功能在不断变化,那么就使用抽象类,如果使用接口,那么每次变更都需要相应的去改变实现该
接口的所有类。
JDK8 中接口的默认方法和静态方法
JDK8中,Oracle引入默认方法和静态方法,用来减少抽象类和接口的差异,可以在接口中提供默认的实现方法并实现该接口的类不用强制去实现这个方法。JDK8中接口的静态方法只能通过接口名直接去调用,接口中的默认方法因为不是abstract的,所以可重写,也可以不重写。