Java大数据之路--abstract(抽象)、接口、内部类

  • 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;
	}
}

 

  • 接口的优点
  1. 约束、模板。(后期开发进行团队合作时候)

  2. 向上造型的类型统一

  •  内部类


类或者接口中再来一个类

先讲类中再定义一个类 (四大类):

  • 方法内部类

即就是在方法中定义一个类,方法内部类中可以定义非静态的属性、方法以及静态常量 ,方法内部类可以继承与实现,但是不能被访问权限修饰符修饰,可以被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(接口中的内部接口)

 

 

猜你喜欢

转载自blog.csdn.net/a34651714/article/details/95313019
今日推荐