java日常记录8 -- 接口以及内部类
  cEe6YWJIAuf2 2023年11月05日 54 0


接java日常记录7

接口

1,什么是接口
接口,这个到底是什么东西?他有什么用呢?
在这里,我们认为普通类:只有具体的实现
抽象类:具体和规范(抽象方法)都有
那么接口嘛:只有规范!
接口用通俗的话讲,接口就是比抽象类还要抽象的抽象类。

下边第一个接口:

public interface Action{
public void Add();
}

注意,接口里边定义的方法必须是public 我们可以选择不写public,将默认为我们定义的方法是public的。
接口中可以不写任何方法,但如果写方法了,该方法必须是抽象方法

2、接口与抽象类的区别

  • 声明类的关键字是class,声明接口的关键字是interface。
  • 抽象类也是类,除了可以写抽象方法以及不能直接new对象之外,其他的和普通类没有什么不一样的
  • 接口是用来被类实现的,java中的接口可以被多实现。

3、接口中的方法都是抽象方法

public interface Action{
	public abstract void run();

	//默认就是public abstract修饰的
	void test();
	public void go();
}

4、接口中的变量都是静态常量(public static final修饰)

接口中可以不写任何属性,但如果写属性了,该属性必须是public static final修饰的静态常量。注:可以直接使用接口名访问其属性。因为是public static修饰的。

注:声明的同时就必须赋值.(因为接口中不能编写静态代码块)

public interface Action{
public static final String NAME = "tom";
//默认就是
public static final修饰的int AGE = 20;
}

5、一个类可以实现多个接口

public class Student implements A,B,C,D{
//Student需要实现接口A B C D中所有的抽象方法
//否则Student类就要声明为抽象类,因为有抽象方法没实现
main:
A s1 = new Student();
B s2 = new Student();
C s3 = new Student();
D s4 = new Student();
}

注:
s1只能调用接口A中声明的方法以及Object中的方法
s2只能调用接口B中声明的方法以及Object中的方法
s3只能调用接口C中声明的方法以及Object中的方法
s4只能调用接口D中声明的方法以及Object中的方法

注:必要时可以类型强制转换

6、一个接口可以继承多个父接口

public interface A{ public void testA();
}
public interface B{ public void testB();
}
public interface C extends A,B{
public void testC();
}

//Student相当于实现了A B C三个接口,需要实现所有的抽象方法
//Student的对象也就同时属于A类型 B类型 C类型
public class Student implements C{
public viod testA(){}
public viod testB(){}
public viod testC(){}
}

main:
C o = new Student();
System.out.println(o instanceof A);//true
System.out.println(o instanceof B);//true
System.out.println(o instanceof C);//true
System.out.println(o instanceof Student);//true
System.out.println(o instanceof Object);//true
System.out.println(o instanceof Teacher);//false

//编译报错
System.out.println(o instanceof String);

7、接口的作用
接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建
【接口名】 【对象名】= new 【实现接口的类】
这样你像用哪个类的对象就可以new哪个对象了,不需要改原来的代码。
假如我们两个类中都有个function()的方法,如果我用接口,那样我new a();就是用a的方法,new b()就是用b的方法
这个就叫统一访问,因为你实现这个接口的类的方法名相同,但是实现内容不同

总结:
1、Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
2、Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化
3、Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法
4、接口中没有构造方法,不能被实例化
5、一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口
6、Java接口必须通过类来实现它的抽象方法
7、当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象

8、不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
9、 一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承.

内部类

1、内部类概述
内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。

  • 内部类分为四种:
    1.成员内部类
    2.静态内部类
    3.局部内部类
    4.匿名内部类

2、成员内部类(实例内部类、非静态内部类)
注:成员内部类中不能写静态属性和方法

//在A类中申明了一个B类,此B类就在A的内部,并且在成员变量的位置上,所以就称为成员内部类
public class Outer {
	private int id;
	public void out(){
	System.out.println("这是外部类方法");
}

class Inner{
	public void in(){
	System.out.println("这是内部类方法");
		}
	}
}

【实例化内部类】
实例化内部类,首先需要实例化外部类,通过外部类去调用内部类

public class Outer { 
	private int id; 
	public void out(){
	System.out.println("这是外部类方法");
}
class Inner{
	public void in(){
		System.out.println("这是内部类方法");
		}
	}
}

public class Test{
	public static void main(String[] args) {
	//实例化成员内部类分两步
	//1、实例化外部类
	Outer outObject = new Outer();
	//2、通过外部类调用内部类
	Outer.Inner inObject = outObject.new Inner();
	//测试,调用内部类中的方法
	inObject.in();//打印:这是内部类方法
	}	
}

【成员内部类能干什么?】
访问外部类的所有属性(这里的属性包括私有的成员变量,方法)

public class Outer {
private int id;
public void out(){
System.out.println("这是外部类方法");
}

class Inner{
public void in(){
System.out.println("这是内部类方法");
}

//内部类访问外部类私有的成员变量
public void useId(){
	System.out.println(id+3);。
}

//内部类访问外部类的方法
public void useOut(){
	out();
		}	
	}
}

public class Test{
	public static void main(String[] args) {
	//实例化成员内部类分两步
	//1、实例化外部类
	Outer outObject = new Outer();
	//2、通过外部类调用内部类
	Outer.Inner inObject = outObject.new Inner();
	//测试
	inObject.useId();//打印3,因为id初始化值为0,0+3就为3,其中在内部类就使用了外部类的私有成员变量id。
	inObject.useOut();//打印:这是外部类方法
	}
}

如果内部类中的变量名和外部类的成员变量名一样,要通过创建外部类对象 "."属性来访问外部类属性,通过this.属性访问内部类成员属性

public class Outer {
	private int id;//默认初始化0
	public void out(){
	System.out.println("这是外部类方法");
	}
	class Inner{
		private int id=8;	//这个id跟外部类的属性id名称一样。
		public void in(){
			System.out.println("这是内部类方法");
		}

		public void test(){
			System.out.println(id);//输出8,内部类中的变量会暂时将外部类的成员变量给隐藏
		
			System.out.println(Outer.this.id);//输出外部类的属性id。也就是输出0
		}
	}
}

System.out.println(Outer.this.id);

3、静态内部类
看到名字就知道,使用你static修饰的内部类就叫静态内部类。
1)static修饰成员变量:整个类的实例共享静态变量
2)static修饰方法:静态方法,只能够访问用static修饰的属性或方法,而非静态方法可以访问static修 饰的方法或属性
3)被static修饰了的成员变量和方法能直接被类名调用。
static不能修饰局部变量,切记,不要搞混淆了,static平常就用来修饰成员变量和方法。

public class StaticInnerClassTest { 
	private String name;
	private static int age;
	public void run(){}

	public static void go(){}
	//外部类访问静态内部类
	public void test(){
			StaticInnerClass sic = new StaticInnerClass(); //静态的内部类不需要依赖外部类,所以不用this
	sic.name = "tom";
	sic.test1("jack");
	
	StaticInnerClass.age=10;
	StaticInnerClass.test2("xixi");
	
	}
	
private static class StaticInnerClass{
	private String name;
	private static int age;
	public void test1(String name){
	System.out.println(name);
	System.out.println(this.name);
	System.out.println(StaticInnerClass.age);
	
	System.out.println(StaticInnerClassTest.age);
	//System.out.println(StaticInnerClassTest.this.name);静态类不能访
	问非静态属性
	
	StaticInnerClassTest.go();
	//StaticInnerClassTest.this.run();静态类不能访问非静态方法
	}
	public static void test2(String name){
	//只能访问自己和外部类的静态属性和方法
	System.out.println(name);
	//System.out.println(this.name);静态方法里面连自己类的非静态属性都不能访问
	System.out.println(StaticInnerClass.age);
	
	System.out.println(StaticInnerClassTest.age);
	//System.out.println(StaticInnerClassTest.this.name);静态方法不能访问非静态属性
	StaticInnerClassTest.go();
	//StaticInnerClassTest.this.run();静态方法不能访问非静态方法
		}
	
    }
}

注意:

1、我们上面说的内部类能够调用外部类的方法和属性,在静态内部类中就行了,因为静态内部类没有 了指向外部类对象的引用。除非外部类中的方法或者属性也是静态的。这就回归到了static关键字的用法。
2、静态内部类能够直接被外部类给实例化,不需要使用外部类对象
Outer.Inner inner = new Outer.Inner();
3、静态内部类中可以声明静态方法和静态变量,但是非静态内部类中就不可以声明静态方法和静态变 量

4、局部内部类
局部内部类是在一个方法内部声明的一个类
局部内部类中可以访问外部类的成员变量及方法
局部内部类中如果要访问该内部类所在方法中的局部变量,那么这个局部变量就必须是final修饰的

public class Outer { 
	private int id;
//在method01方法中有一个Inner内部类,这个内部类就称为局部内部类
	public void method01(){
 	class Inner{ public void in(){
		System.out.println("这是局部内部类");
			}
		}
	}
}

注意:
在局部内部类中,如果要访问局部变量,那么该局部变量要用final修饰

1.为什么需要使用final?
final修饰变量:变为常量,会在常量池中放着,逆向思维想这个问题,如果不实用final修饰,当局部内部类被实例化后,方法弹栈,局部变量随着跟着消失,这个时候局部内部类对象在想去调用该局部变
量,就会报错,因为该局部变量已经没了,当局部变量用fanal修饰后,就会将其加入常量池中,即使方法弹栈了,该局部变量还在常量池中呆着,局部内部类也就是够调用。所以局部内部类想要调用局部变 量时,需要使用final修饰,不使用,编译度通不过。

public class Outer {
	private int id;
	public void method01(){
	final int cid = 3;	//这个就是局部变量cid。要让局部内部类使用,就得变为final并且赋值,如果不使用final修饰,就会报错
class Inner{
//内部类的第一个方法
	public void in(){
		System.out.println("这是局部内部类");
	}
//内部类中的使用局部变量cid的方法
public void useCid(){
		System.out.println(cid);
		}
	}

	}
}

局部内部类不能通过外部类对象直接实例化,而是在方法中实例化出自己来,然后通过内部类对象 调用自己类中的方法

5、匿名内部类
什么是匿名对象?
如果一个对象只要使用一次,那么我们就是需要new Object().method()。 就可以了,而不需要给这个实例保存到该类型变量中去。这就是匿名对象。

public class Test {
		public static void main(String[] args) {
//讲new出来的Apple实例赋给apple变量保存起来,但是我们只需要用一次,就可以这样写
	Apple apple = new Apple();
		apple.eat();
//这种就叫做匿名对象的使用,不把实例保存到变量中。
		new Apple().eat();
	}
}
class Apple{
	public void eat(){
	 System.out.println("我要被吃了");
	}

1.匿名内部类需要依托于其他类或者接口来创建
如果依托的是类,那么创建出来的匿名内部类就默认是这个类的子类
如果依托的是接口,那么创建出来的匿名内部类就默认是这个接口的实现类。
2.匿名内部类的声明必须是在使用new关键字的时候
匿名内部类的声明及创建对象必须一气呵成,并且之后能反复使用,因为没有名字。
【使用匿名内部类】

public class Test{
	public static void main(String[] args) {
	//如果我们需要使用接口中的方法,我们只需要走一步,就是使用匿名内部类,直接将其类的对象创建出来。
	new Test1(){
	public void method(){
			System.out.println("实现了Test接口的方法");
			}
	}.method();

	}
}

interface Test1{
		public void method();
	}
	
}

其实只要明白一点,new Test1(){实现接口中方法的代码}; Test1(){…}这个的作用就是将接口给实现了,只不过这里实现该接口的是一个匿名类,也就是说这个类没名字,只能使用这一次,我们知道了这是一个类, 将其new出来,就能获得一个实现了Test1接口的类的实例对象,通过该实例对象,就能调用该类中的方法了,因为其匿名类是在一个类中实现的,所以叫其匿名内部类,不要纠结为什么Test1(){…}就相当于实现了Test1接口,这其中的原理等足够强大 了,在去学习,不要钻牛角尖,这里就仅仅是需要知道他的作用是什么,做了些什么东西就行。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: Oracle TRUNCATE 下一篇: java日常记录4--数组
  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
cEe6YWJIAuf2