一、super
-
super的意思是超级的,主要是和父类有关
-
用法
-
调用父类的构造方法
如果父类有默认构造方法,则可以不用super,但是,如果父类只有有参构造方法,此时,在创建子类对象时,在子类的构造方法中就要显示的调用super构造方法
class Father{}
Son son = new Son()
执行new Son()时先执行new Father();
以上代码是默认构造方法,JVM可以自动调用,用不上super
真实运行时这样的:
class Son extends Father{
public Son(){
super();
}
}-- 以上是默认的构造方法,如果父类没有默认构造方法,就要显示调用,此时使用super。
public class Father {
public Father(String name) {
System.out.println("father" + name);
}
}
class Son extends Father{
public Son(String name) {
super(name);
}
}-- 如果父类的构造方法不是默认的,子类必须要有和它匹配的构造方法,重点是:在子类中使用super调用父类的构造方法,并且传入参数。
-- super在子类构造方法中必须是第一行代码。
-
用super调用子类覆盖的父类的方法
比如:父类有say(),子类也有say(),并且say被覆盖,如果在子类中想要调用父类的say方法,只能使用super.say();
public class Father {
public Father(String name) {
System.out.println("father" + name);
}
public void say() {
System.out.println("father say");
}
/**
* 调用this,此时this是谁,多态的知识点,不管this代码在哪里,关键是看声明,
* Father son = new Son(),指向的是son的say
* Father father = new Father(),指向的是father的say
*
*/
public void fatherTest() {
this.say();
}
}
class Son extends Father{
public Son(String name) {
super(name);
}
-
-
多态:this.say(),关键是看声明的时候创建的是谁的实例,
二、instanceof和强转
instanceof运算符是特殊的运算符,可以判断某个对象是否某个类的实例。 如果B是A的子类,则: A obj = new B(); 赋值号= 左边是大类型,基本类型,右边是子类型,则可以自然转换,如:Chinese obj = new Shanxi(); if (obj instanceof B) 则B b = (B)obj;当检查到obj实际身份是B时,可以还原其身份到B类型,但此时obj的外在身份依然是A,所以转换时还是要加括号进行强转,强转的前提是类型正确,比如C也是A的子类,上面的obj就不能强转成C,会报类型转换错误的异常。
三、接口
-
interface 类的行为规范
-
类有什么用?实现某些业务,存储数据,传递数据(方法的参数)
POJO,Java原始类,这样的类用来存储数据和传递数据,bean包,entify包(类似于这些放简单类的包)下都是POJO
-
JDK8之前,接口中只有抽象方法和常量,接口中的所有的方法默认都是抽象的,所以在定义方法时不用写public和abstract。
void say();//等价于public abstract void say();
接口中的变量都是常量,因为变量会默认加上public static final,
int UPDATE_SUCCESS = 1;// 等价于 public static final
常量的命名要大写,单词和单词之间用“_”隔开
-
JDK8开始,接口中有了默认方法,这些方法有方法体,方法用关键字default定义,接口不用来实现业务,只定义行为要求,需要做什么,具体实现细节由接口的实现类来完成。如果一个接口中有N个方法,实现类就要实现N个方法,如果没有实现所有的方法,则该类是抽象类。
在JDK原码中,有大量的实现接口没有完全实现的抽象类,他们可以分层次的去实现.
有的项目组接口的定义规则是以"I"开头,实现类以”impl“结束
implement实现,impl是缩写
java中的继承是单继承的,只能有一个父类,java中可以同时实现多个接口。
public class Son extends Father implement IAnimal,IDao{
}接口时不能创建实例的,接口可以使用多态的技术,具有父类的效果。接口中的方法是抽象的,抽象类中的方法是对接口中的方法的重写,这也体现出父类和子类的特点。
-
-
接口特点
-
不能创建实例
-
只能定义常量
-
普通方法都为抽象方法
-
default方法可以有方法体
-
类可以同时实现多个接口
-
-
抽象类特点
-
抽象类不能创建实例
-
可以定义抽象方法和普通方法
-
单继承
-
-
接口1和接口2中的方法相同,实现一个另外一个自动实现
-
当接口1和接口2中有相同的方法,但是返回值不兼容,实现类无法实现这两个类。
-
如果接口1和接口2的返回值兼容,即使不一样,实现类也可以同时实现两个方法。
结论:Java中的单继承是指类的单继承,接口可以多继承
接口继承多个接口时,多个接口中不能有冲突的方法存在
当一个类同时实现一个接口和继承一个父类时,父类和接口中的方法也不能冲突。
四、包
-
包是用来管理类的,可以避免同名类的冲突,每个包有相应的功能,包下的类就是这相应功能的类。
通常工程中的类有几大功能:
控制器类,业务类,数据库类,POJO类
根据这些功能建对应的包:controller包,service包,dao包,bean包
不同的包下放同一类功能的类
包的另一个功能,管理权限。
修饰符,访问修饰符:private<default(不写)<protected<public
类内部 包内部 继承 包外(不继承) public OK OK OK OK protected OK OK OK NO default(不写) OK OK NO NO private OK NO NO NO 包内:包里有A,B两个类,A中的public,protected,default成员都可以在B中访问,A中的private不可以
继承:包1中有A,包2中有B,B类继承A类,B类只能访问A类中的public和protected,default和private不能访问,default只能在同一个包下互相访问,出了包不可以,protected因为继承的关系,在不同的包下可以访问。
-- 如果父类和子类分别在不同的包下,父类中的default修饰的成员无法在子类中访问,但是protected可以访问
五、内部类
包1下定义一个类,该类不是public,是默认的,包2无法访问。
内部类:定义在一个类内部的类。它可以定义在一个类中的属性的区域或方法中,或一个代码块中,if,for
内部类可以有名字,可以没有名字(匿名内部类),匿名内部类多用于抽象类或接口的实例化(抽象类和接口本身是不能创建实例的,但是可以通过匿名内部类简介实现)
内部类的优点:它可以具有类的功能,但是只限于当前类使用,不对外,否则就定义成一个外部的类,可以组织代码,使得代码结构清晰。内部类可以绕开Java的单继承,如果外部类继承了一个类,而此时还想继承另一个类,就让内部类来继承它。
两点:第一点:别人不用,自己用;第二点:内部类可以定义成为方法来使用,但是方法有局限性,当一个方法完成不了时,需要定义成一个类,方法升级为内部类后,功能增强。
内部类可以访问外部类的数据(注意静态的使用,如果内部类是静态的,则情况复杂),静态内部类只能访问外部类的静态数据
分类:
-
成员内部类
-
成员内部类
-
静态成员内部类
public class Outer {
int id = 1;
/**
* 成员内部类
*/
class Inner1{
public void say() {
System.out.println("Inner1 say");
}
}
/**
* 静态成员内部类
*/
static class Inner2{
public void say() {
System.out.println("Inner2 say");
}
}
public static void main(String[] args) {
Outer outer = new Outer();
// 访问类的成员
System.out.println(outer.id);
Outer.Inner1 inner1 = new Outer().new Inner1();
// inner1.say();
Outer.Inner2 inner2 = new Outer.Inner2();
inner2.say();
}
} -
-
方法内部类
public void work() {
/**
* 方法内部类只能在方法内部使用
*/
class Inner1{
public Inner1(){
System.out.println("method Inner1 created");
}
void work() {
System.out.println("method Inner1 work");
}
}
Inner1 inner1 = new Inner1();
inner1.work();
} -
块内部类
public void work2() {
if (id > 0) {
/**
* 块内部类
*/
class Inner1{
public Inner1() {
System.out.println("if block Inner1 created");
}
}
Inner1 inner1 = new Inner1();
}
}
-
匿名内部类
public class Worker {
private int age = 10;
public void test() {
AbstractWorker abstractWorker = new AbstractWorker() {
int id;