-
abstract(抽象)
所有子类对父类的某个方法都进行了不同程度的重写,父类的这个方法的方法体没有实际含义,就可以把我们的方法体去掉,用abstract修饰就变成了抽象方法,如果一个类中出现了抽象方法,这个类就要变成抽象类。抽象方法一定要被重写、如果一个普通类继承了抽象类就要把所有的抽象方法都要进行重写,如果不想进行重写就可以把普通类变成抽象类。
abstract是关键字 修饰符可以修饰------方法、类
- 抽象方法
抽象方法可以重载吗?--------可以重载。
//可以重载
public abstract double girth();
public abstract double girth(int i);
抽象方法可以被static/final/private分别修饰?----------不行,不能进行重写
- 抽象类
抽象类一定含有抽象方法吗? 不一定
抽象类可以创建对象吗? 类中含有构造方法,但是是C语言通过这个构造方法创建出了对象,但是对于JAVA而言拿不到,所有就是没有对象。
// 抽象类Shape,这个S是这个匿名内部类的对象 $是内部类,
Shape s = new Shape(1,2) {
@Override
public double girth() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double area() {
// TODO Auto-generated method stub
return 0;
}
};//匿名内部类,
抽象类可以被final修饰? 不可以,最终类不能被继承,重写的前提是继承。
-
interface(接口)
一个抽象类中所有方法都是抽象方法就可以转成接口,用interface来表示,一个普通类可以通过implements让类与接口之间产生关联关系-----实现,并且支持多实现(一个类可以实现多个接口),类实现了接口之后就要重写所有的抽象方法,如果不想重写可以把类变成抽象类,接口与接口之间是多继承--------接口可以同时继承多个接口,接口不是个类。
public class AbstractDemo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
//interface----接口-----不是类 , 全是抽象方法
//接口与接口之间通过extends产生了继承
//接口与接口之间是多继承
interface Shape1 extends Object,Cloneable {
public abstract double getGirth();
public abstract double getArea();
}
//类和接口之间产生关系 implements:实现
//实现的方式是多实现----类可以实现多个接口
//一个普通类去实现一个接口就要重写所有的抽象方法
//如果不想重写所有的抽象方法就可以变成抽象类
abstract class Rectangle1 implements Shape1,Cloneable{}
接口中可以创建对象?(看是否有构造方法) 不可以,接口不能定义构造方法,因此不能创建对象。
接口中可以定义属性?()可以但是会默认被public final static修饰。
接口中的方法默认被public abstract修饰。
interface Shape1 extends Object,Cloneable {
//默认被public final static修饰
public final static int i=10;
//默认被public abstract修饰,注意重写时候只能用public
void m();
public abstract double getGirth();
public abstract double getArea();
}
public class InterfaceDemo2 {
public static void main(String[] args) {
//向上造型对象
B b = new C();
//编译运行没错
//在编译时期,针对两个对象的声明类是否具有继承关系,如果有继承关系就编译通过
//c的声明类是C类,b的声明类是B,B类和C类有继承关系,编译通过
//在运行时期,针对两个对象的实际创建类是否一致,如果一致才能运行通过
//c的实创建类是C,b实际创建类也是C类,一致就运行通过
//向下造型
C c = (C) b;
//java.lang.ClassCastException----类型转换异常
//编译没错,运行有错
//d声明类是D类,b声明类是B类,之间有继承关系,编译通过
//d的实际创建类是D类,b的实际创建类是C类不一致,运行报错
//D d = (D) b;
//编译报错
//因为的d的声明类是D,c的声明类是C类,没有继承关系,编译不通过
//d=(D)c;
System.out.println("over");
}
}
class B{}
class C extends B{}
class D extends B{}
- 向下转型
class A{......}
class B extends A{ }
A a = new B();//当我们有个向上造型的对象,能调用所有父类方法,和B类中的重写方法。
B b =(B)a;//如果我们需要调用B类中没有重写的其他方法需要进行向下造型。先有向上才有向下造型
接口类型可以接受所有引用类型的值的转换
public class InterfaceDemo2 {
public static void main(String[] args) {
//向上造型对象
B b = new C();
//编译运行没错
//在编译时期,针对两个对象的声明类是否具有继承关系,如果有继承关系就编译通过
//c的声明类是C类,b的声明类是B,B类和C类有继承关系,编译通过
//在运行时期,针对两个对象的实际创建类是否一致,如果一致才能运行通过
//c的实创建类是C,b实际创建类也是C类,一致就运行通过
//向下造型
C c = (C) b;
//java.lang.ClassCastException----类型转换异常
//编译没错,运行有错
//d声明类是D类,b声明类是B类,之间有继承关系,编译通过
//d的实际创建类是D类,b的实际创建类是C类不一致,运行报错
//D d = (D) b;
//编译报错
//因为的d的声明类是D,c的声明类是C类,没有继承关系,编译不通过
//d=(D)c;
//类 是一个树状结构,单继承,能快速检测两个类之间的关系,在编译和运行java都加了检测
//类与接口之间是多实现,是一个网状结构,不能快速检测两个类型的关系,在编译时期不检测,在运行时期检测类型之间是否有实现关系
A a =(A)b;
A a1 =(A)c;
System.out.println("over");
}
}
interface A{}
class B implements A{}
class C extends B{}
class D extends B{}
接口中全部都是抽象方法? ------不一定 jdk1.8以前接口中都是抽象方法,从jdk1.8开始允许在接口中定义实体方法
- jdk1.8在接口的新特性
在接口中定义实体方法:
两种形式 加上default或者static修饰符
interface Calc{
//求和
//实体方法 ----被default修饰-----变成了默认实体方法
public default int sum(int m,int n){
return m+n;
}
//求乘积
//实体方法-----被static修饰------静态实体方法
public static int cj(int m,int n){
return m*n;
}
}
通过Lambda表达式对接口中的抽象方法进行重写,保证接口中只有一个抽象方法,一个接口中只有一个接口只有一个抽象方法我们称之为函数式接口
public class InterfaceDemo3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Lambda表达式从1.8开始支持 只能支持一个接口中只有一个抽象方法
//(参数列表)->{重写方法的方法体}
//Calc c =(int m,int n)->{return m>n?m:n;};
//如果方法只有一行代码就可以省略return以及{}
//Calc c = (int m,int n)->m>n?m:n;
//由接口中的抽象方法可以推导出参数类型,在此时可以不用类型表示
Calc c=(m,n)->m>n?m:n;
}
}
//接口----代表计算器
//如果想要使用Lambda表达式需要保证接口中只有一个抽象方法
//如果一个接口中只有一个抽象方法,这个接口就叫做函数式接口
//注解:@FunctionalInterface 能加上就是函数式接口
@FunctionalInterface
interface Calc{
//求两个整数最大值
//抽象方法
int max(int m, int n);
//求和
//实体方法 ----被default修饰-----变成了默认实体方法
public default int sum(int m,int n){
return m+n;
}
//求乘积
//实体方法-----被static修饰------静态实体方法
public static int cj(int m,int n){
return m*n;
}
}
- 接口的优点
-
约束、模板。(后期开发进行团队合作时候)
-
向上造型的类型统一
-
内部类
类或者接口中再来一个类
先讲类中再定义一个类 (四大类):
-
方法内部类
即就是在方法中定义一个类,方法内部类中可以定义非静态的属性、方法以及静态常量 ,方法内部类可以继承与实现,但是不能被访问权限修饰符修饰,可以被final以及abstract修饰
方法内部类可以获取外部类的所有属性和方法
方法内部类只能拿到本方法中的常量
public class InnerDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Outer1 o = new Outer1();
o.m(); //调用方法,内部类对象创建 输出结果
}
}
class Outer1{
//属性
private int j=1;
//方法
public void m(){
int a = 0;//jdk1.8特性 隐式常量:内部类中这个变量默认在底层添加一个final
//a=1;//jdk1.8以前就是一个显式常量:必须手动添加final
//方法内部类
//可以定义非静态的属性和方法以及静态常量
// only abstract or final is permitted
//不能被访问权限修饰符修饰,可以被final或者abstract修饰
//内部类可以获取外部类所有信息包括静态非静态包括private
//内部类获取本方法中的信息一定是常量
class Inner1 {//问???一个内部类如何创建对象
int i=10;
public void mn(){
System.out.println(j+a);
n();
}
}
//创建对象 在方法内
Inner1 i = new Inner1();
i.mn();
}
public void n(){}
}
- 成员内部类
即就是在类内方法外定义一个类, 成员内部类中可以定义非静态的属性、方法以及静态常量 ,成员内部类可以继承与实现,能被访问权限修饰符修饰,可以被final以及abstract修饰
可以获取外部类的所有属性和方法
Outer2.Inner2 in2 = new Outer2().new Inner2();//创建成员内部类对象方式
public class InnerDemo2 {
public static void main(String[] args) {
//成员内部类创建对象
Outer2.Inner2 in2 = new Outer2().new Inner2();
in2.n();
}
}
class Outer2{
//属性
int x=1;
//成员内部类
//可以定义非静态属性和方法以及静态常量
//可以继承与实现,可以被访问权限修饰符修饰以及final、abstract
//可以拿到外部类的所有属性和方法
//private class Inner2 extends Outer2 implements Cloneable{
class Inner2 extends Outer2 implements Cloneable{
int i=1;
public void n(){System.out.println(x);}
}
//方法
public void m(){}
}
- 静态内部类
即成员内部类加上static,静态内部类可以定义任意信息,可以继承与实现,可以被访问权限修饰符修饰以及final、abstract修饰,只能获取外部类的静态信息
Outer3.Inner3 in3 = new Outer3.Inner3();//静态内部类创建的对象
public class InnerDemo3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//静态内部类创建的对象
Outer3.Inner3 in3 = new Outer3.Inner3();
in3.n();
}
}
class Outer3{
static int i=1;
//静态内部类
//可以定义任意信息以及静态常量
//可以继承与实现
//可以被访问权限修饰符修饰以及final和abstract修饰
//只能获取到外部类的静态信息
static class Inner3{
int k=10;
public void n(){
System.out.println(i);
}
}
public void m(){}
}
- 匿名内部类
{}----用于去继承类或者实现接口,重写方法
如果匿名内部类在方法内就按方法内部类使用
若果匿名内部类在成员位置就按成员内部类使用
public class InnerDemo4 {
//匿名内部类在成员位置,按照成员内部类来使用
AB a = new AB(){};
public static void main(String[] args) {
int j=10;
// TODO Auto-generated method stub
//创建对象
//匿名内部类----{}
//匿名内部类在继承抽象类,重写方法
//匿名内部类在继承类(可以被继承)/实现接口,重写方法
//如果匿名内部类在方法内就按方法内类来使用
AD d = new AD() {
@Override
public void m() {
// TODO Auto-generated method stub
System.out.println(j);
}
};
//{}---匿名内部类---继承C类
CC c = new CC(){};
//{}---匿名内部类实现接口
AB b = new AB(){};
}
}
interface AB{}
class CC{}
//
abstract class AD{
public abstract void m() ;
}
-
接口中的类
接口中的内部类默认是静态的
public class InnerDemo5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(aa.Inner5.i); //10
System.out.println(aa.bb.j); //4
System.out.println(aa.Inner5.c.k); //5
}
}
interface aa{
//默认被static修饰
static class Inner5{
static int i=10;
//默认被static修饰
interface c{
int k=5;
}
}
//内部接口
//默认被static修饰
static interface bb{
int j =4;
}
}
-
内部接口
类或者接口中再来一个接口,接口默认都是静态的。图同上中接口c(内部类中的接口)和接口bb(接口中的内部接口)