day11
- 接口
1.1 接口的概念
接口: 一个规则的限定,就是用于定义规则
接口存在的意义: 接口出现可以实现解耦特点,因为接口中定义的都是抽象方法,相当于只有方法的定义,没有方法实现. 等着类去实现, 体现出方法的定义和实现做分离
1.2 接口的定义
使用关键字 : interface , 表示接口的含义
定义类 : 修饰符 class 类名{}
定义接口:
修饰符 interface 接口名{
// 抽象方法
}
- 接口的源文件,是一个.java文件,编译之后是一个.class文件
- 接口中的方法,都是抽象方法
代码
// 定义一个接口
public interface MyInterface {
// 在接口中定义抽象方法
public abstract void fun1();
public abstract int getSum(int x , int y);
}
1.3 接口的实现
- 接口不能实例化对象
- 接口需要类来实现
类与类之间的关系,叫做继承关系,extends
class A extends B{}
类与接口之间的关系,叫实现关系, implements 表示实现的含义
public interface MyInterface{}
class MyInterfaceImpl implements MyInterface{}
类实现一个接口之后
- 将接口中的所有抽象方法全部重写,使用@Override证明是接口中方法重写,这个类就是一个普通的类,可以实例化对象,通过对象名.调用重写的方法
- 没有将接口中的所有的抽象方法全部抽象(一个都没重写,只重写了一部分),这个类中就存在从父类接口中继承来的抽象类,这个类就是一个抽象类
代码
// 定义一个接口
public interface MyInterface {
// 在接口中定义抽象方法
public abstract void fun1();
public abstract int getSum(int x , int y);
}
// 定义一个没有将父接口中所有方法全部重写的抽象实现类
public abstract class MyInterfaceImpl2 implements MyInterface{
// 类中还存在一个抽象的fun1方法
@Override
public int getSum(int x , int y){
return (x + y)*2 ;
}
}
// 定义一个类,MyInterfaceImpl实现接口MyInterface
public class MyInterfaceImpl implements MyInterface{
// 1. 将接口中的所有抽象方法全部重写
public int getSum(int x , int y){
System.out.println("重写了getSum这个抽象方法");
return x + y;
}
public void fun1(){
System.out.println("重写了fun1这个抽象方法");
}
public static void main(String[] args) {
MyInterfaceImpl my = new MyInterfaceImpl();
my.fun1();
System.out.println(my.getSum(3,5));
//MyInterfaceImpl2 my2 = new MyInterfaceImpl2();
//System.out.println(my2.getSum(3,5));
}
}
1.4 接口中的成员
- 接口中定义常量, 其实这些常量,都是使用public static final默认修饰的变量
- 接口中定义抽象方法, 都是默认使用public abstract 修饰
- 接口中没有构造方法
代码
// 定义一个接口
public interface MyInterface {
//1. 定义常量,默认使用public static final 修饰
final int i = 10;
// 2. 在接口中定义抽象方法
public abstract void fun1();
public abstract int getSum(int x , int y);
// 3. 接口中所有的抽象方法默认使用public abstract
void eat();
}
// 定义一个类,MyInterfaceImpl实现接口MyInterface
public class MyInterfaceImpl implements MyInterface{
// 1. 将接口中的所有抽象方法全部重写
@Override
public int getSum(int x , int y){
System.out.println("重写了getSum这个抽象方法");
return x + y;
}
@Override
public void fun1(){
System.out.println("重写了fun1这个抽象方法");
}
public void eat(){
System.out.println("重写了eat这个抽象方法");
}
public static void main(String[] args) {
MyInterfaceImpl my = new MyInterfaceImpl();
my.fun1();
System.out.println(my.getSum(3,5));
my.eat();
//MyInterfaceImpl2 my2 = new MyInterfaceImpl2();
//System.out.println(my2.getSum(3,5));
}
}
public class TestInterface {
public static void main(String[] args) {
// 证明了接口中的常量默认使用static修饰
System.out.println(MyInterface.i);
// 证明了接口中的常量默认使用final修饰
MyInterface.i = 99;
}
}
1.5 类与类,类与接口,接口与接口之间的关系
- 类与类 : 继承关系,使用extends关键字,
继承的特征 : 只能单继承(一个子类只能有一个直接父类),但是可以多层继承
class A extends B{}
class B extends C{}
A类只能有一个直接父类B,B类只有一个直接父类C类(单继承)
A类可以同时拥有B和C两个类的内容(多层继承)
2.类与接口 : 实现关系,使用implements 关键字
实现的特征 :
1)一个类可以同时实现多个接口
interface A{}
interface B{}
class C implements A,B{
// 类C需要同时将A和B两个接口中的所有抽象方法全部重写
}
2)类继承一个类的同时,还是实现多个接口
- 接口与接口: 继承关系,extends关键字, 接口之间可以多继承
代码
// 定义一个接口
public interface MyInterface {
//1. 定义常量,默认使用public static final 修饰
final int i = 10;
// 2. 在接口中定义抽象方法
public abstract void fun1();
public abstract int getSum(int x , int y);
// 3. 接口中所有的抽象方法默认使用public abstract
void eat();
}
// 定义的一个接口
public interface InterfaceA{
public abstract void sleep();
}
// 定义一个类,MyInterfaceImpl实现接口MyInterface和InterfaceA
public class MyInterfaceImpl implements MyInterface,InterfaceA{
// 1. 将接口中的所有抽象方法全部重写
@Override
public int getSum(int x , int y){
System.out.println(“重写了getSum这个抽象方法”);
return x + y;
}
@Override
public void fun1(){
System.out.println("重写了fun1这个抽象方法");
}
public void eat(){
System.out.println("重写了eat这个抽象方法");
}
@Override
public void sleep(){
System.out.println("重写了sleep这个抽象方法");
}
public static void main(String[] args) {
MyInterfaceImpl my = new MyInterfaceImpl();
my.fun1();
System.out.println(my.getSum(3,5));
my.eat();
my.sleep();
//MyInterfaceImpl2 my2 = new MyInterfaceImpl2();
//System.out.println(my2.getSum(3,5));
}
}
//定义一个父类
public class Fu{
public void getFu(){
System.out.println(“Fu的method”);
}
}
// 一个类继承一个类的同时,实现多个接口
public class Zi extends Fu implements MyInterface,InterfaceA {
// Zi继承了Fu类中的getFu
// 1. 将接口中的所有抽象方法全部重写
@Override
public int getSum(int x , int y){
System.out.println("Zi重写了getSum这个抽象方法");
return x + y;
}
@Override
public void fun1(){
System.out.println("Zi重写了fun1这个抽象方法");
}
public void eat(){
System.out.println("Zi重写了eat这个抽象方法");
}
@Override
public void sleep(){
System.out.println("Zi重写了sleep这个抽象方法");
}
}
// 接口与接口之间的多继承
public interface ZuiHouInterface extends MyInterface,InterfaceA {
}
1.6 抽象类与接口的使用场景
注意 : 抽象类和接口,都可以使用多态
多态 : 具有继承关系或者具有实现关系 ;父类的引用指向子类对象
抽象类 c = new 子类(); // 继承关系
c.方法(); // 调用子类重写方法
接口 i = new 实现类(); // 实现关系
i.方法(); // 调用实现类的重写方法
- 内部类
2.1 内部类的概述
将一个类定义在另外一个类的内部
根据定义的位置不同,功能和使用方式也不同
Car类,属性,功能
发动机 : 属性和很多的功能
内部类的分类:
根据定义的位置不同
- 成员内部类 (定义在类中方法外)
- 布局内部类 (定义在方法中)
匿名内部类
2.2 成员内部类(了解)
定义在类中方法外
2.2.1 普通的成员内部类
定义格式:
理解: 将内部类理解成一个成员变量,只不过这个成员变量是一个类而已
修饰符 class 内部类名{
// 属性
// 方法
}
说明:
- 外部类中的成员变量,可以在内部类中使用
- 内部类中,可以定义属性,方法
- 外部类要使用内部类的属性和成员,先创建内部类的对象出来
- 内部类在其他类中使用,创建方式
外部类.内部类 名 = new 外部类().new 内部类();
代码
// 定义一个普通成员内部类
public class Body {
int heigth = 120 ;
// 定义一个成员内部类
public class Heart{
int jump = 80 ;
public void heartJump(){
System.out.println("血压为"+heigth + ",心脏每分钟跳"+jump +"下");
}
}
// 要求 : 让heartJump方法运行
public void useHeart(){
Heart h = new Heart();
h.heartJump();
}
}
// 测试内部类的使用
public class TestBody {
public static void main(String[] args) {
// 1. 测试成员内部类,普通的成员内部类
Body b = new Body();
b.useHeart();
// 2. 内部类在其他类中使用,创建方式
// 外部类.内部类 名 = new 外部类().new 内部类();
Body.Heart bh = new Body().new Heart();
bh.heartJump();
}
}
2.2.2 私有成员内部类
定义格式:
理解: 将内部类理解成一个成员变量,只不过这个成员变量是一个类而已
private class 内部类名{
// 属性
// 方法
}
说明 :
内部类私有,只能在当前外部类中使用,在其他类中,不能直接创建内部类对象使用
在外部类的内部,提供对外的公共访问的方式 : 在外部类中定义一个方法,方法中穿件私有内部类,调用私有内部类中方法
代码
// 定义一个外部类Body1
public class Body1{
String color = “balck”;
private class Fei{
int count = 20 ;
public void smoke(){
System.out.println("每天吸"+count + "跟烟,肺就会变成"
+color +"颜色");
}
}
public void useFei(){
Fei fei = new Fei();
fei.smoke();
}
}
// 测试内部类的使用
public class TestBody {
public static void main(String[] args) {
//测试私有成员内部类
Body1 b1 = new Body1();
b1.useFei();
}
}
2.2.3静态成员内部类
定义格式:
理解: 将内部类理解成一个成员变量,只不过这个成员变量是一个类而已
static class 内部类名{
// 属性
// 方法
}
说明 :
- 内部类是一个静态的修饰,可以使用外部类名.直接调用内部类
- 如果静态内部类中定义的属性和方法,不是静态的,就需要创建出静态内部类对象,然后通过对象名的方法,调用静态内部类中的成员
- 静态成员内部类的创建方式:
外部类名.静态内部类名 名字 = new 外部类名.静态内部类名();
代码
public class Body2{
static int day = 1;
static class Gan{
int zhong = 10;
public void drink(){
System.out.println(day + "天,喝"+zhong + "斤白酒,大哥别喝了,受不住了");
}
}
}
// 测试内部类的使用
public class TestBody {
public static void main(String[] args) {
//测试静态成员内部类
Body2.Gan b2 = new Body2.Gan();
b2.drink();
}
}
2.3 局部内部类(了解)
定义格式:
理解: 将局部内部类理解成一个局部变量,只不过这个变量是一个类而已
class 局部内部类名{
// 属性
// 方法
}
说明 :
- 需要定义在方法内部
- 局部内部类,在类定义结束后,在方法中,创建布局内部类对象,通过对象名.调用局部内部类中的方法
代码
public class Body3{
public static void WC(){
// 喝水的升数
int i = 10;
// 定义一个局部内部类,相当于一个局部变量
class shen{
// 上j趟卫生间
int j = 10 ;
public void toWC(){
System.out.println("每天喝"+i+"升水,去卫生间"+j+"趟");
}
}
// 局部内部类,在类定义结束后,在方法中,创建布局内部类对象
// 通过对象名.调用局部内部类中的方法
shen sh = new shen();
sh.toWC();
}
public static void main(String[] args) {
WC();
}
}
2.4 匿名内部类(重要)
匿名内部类 :
匿名 : 没有名字的
内部类 : 定义在方法中
匿名内部类的使用功能 :
可以作为一个父类的子类或者是一个接口的实现类,简化接口或者是抽象类的实现过程
匿名内部类的写作规范:
new 父类或者接口(){
// 一对大括号的内部,就是父类的子类或者是接口的实现类
};
代码
// 定义一个匿名的内部类
public class NiMingNeiBuLei{
public static void main(String[] args) {
// 1. 定义接口的实现类,通过创建实现类对象,调用重写方法
MyInterImpl my = new MyInterImpl();
my.eat();
// 2. 匿名对象调用
new MyInterImpl().eat();
// 3. 定义一个匿名的内部类,实现接口MyInter
new MyInter(){// 就是MyInter的一个实现类
// 必须将MyInter接口中的所有抽象重写
@Override
public void eat(){
System.out.println("匿名内部类实现eat功能");
}
}.eat();
}
}
interface MyInter{
public abstract void eat();
}
class MyInterImpl implements MyInter{
public void eat(){
System.out.println(“实现eat功能”);
}
}
有名内部类,通过多态实现升级
代码
// 定义一个匿名的内部类
public class NiMingNeiBuLei{
public static void main(String[] args) {
MyInterImpl my = new MyInterImpl();
my.eat();
// 匿名对象
new MyInterImpl().eat();
// 1. 定义一个匿名的内部类
new MyInter(){// 就是MyInter的一个实现类
// 必须将MyInter接口中的所有抽象重写
@Override
public void eat(){
System.out.println("匿名内部类实现eat功能");
}
}.eat();
// 2. 多态: 父类(父接口)的引用指向子类对象
MyInter2 my2 = new MyInter2(){
// 必须将MyInter2接口中的所有抽象重写
@Override
public void sleep(){
System.out.println("匿名内部类实现sleep功能");
}
@Override
public void function(){
System.out.println("匿名内部类实现function功能");
}
};
my2.sleep();
my2.function();
}
}
interface MyInter{
public abstract void eat();
}
interface MyInter2{
public abstract void sleep();
public abstract void function();
}
class MyInterImpl implements MyInter{
public void eat(){
System.out.println(“实现eat功能”);
}
}
-
导包 :
ctrl + shift + o : 能将代码中所有需要导入的包,一次性导入 -
注释 :
单行注释 : ctrl + / , 取消单行注释 : ctrl + /多行注释 : 先选中要注释的行数, ctrl + shift + /
取消多行注释 ctrl + shift + \ -
重命名 : F2 键
-
删除单行 : ctrl + d : 每次删除一行代码,删除鼠标所在行的代码
-
包
-
包的创建
项目工程中,project 下面可能会有很多包,每一个包对应磁盘上面的一个文件夹,项目中,会将一类的文件放置在同一个包中,便于维护和使用
创建包 : 使用package进行创建
在src源文件路径下,创建包,使用package -
包的作用:
创建一个类的时候,在包下面进行创建
不同的包下面可以创建相同的类文件
Java中类的名字 : 带有包名的全类名
Scanner-----> java.util.Scanner sc = new java.util.Scanner();
Scanner sc = new Scanner();
import : 导包,import java.util.Scanner;
注意 : 当使用不再同一个包下的其他类时,记得导包
- 权限修饰符
权限 : 指修饰的类或者变量,方法,使用范围有多大
public 公共的
protected 受保护的
default 默认权限, 当没有给类,变量,方法任何修饰符,那么就是默认修饰, 默认权限default不能写出来,系统自动为你添加的,写出来范围报错
private 私有的
权限/使用范围 本类中使用 本包中使用 外包中子类 外包中无关类(整个项目中)
protected : 使用protected修饰的方法和变量只能在外包的子类内部使用,在子类内部相当于private使用级别,protected 不修饰类
四种权限从大到小排序:
public----->protected---->默认的---->private
注意: 实际开发中,类和方法多数都是public修饰,类中的成员变量,使用private修饰
public可以在整个项目中使用代码
package com.zgjy.demo1;
public class Animal {
public void sleep() {
System.out.println(“睡觉”);
}
}
package com.zgjy.demo;
import com.zgjy.demo1.Animal;
public class Hello {
public static void main(String[] args) {
// public修饰的类,可以在整个项目中使用
Animal a = new Animal();
a.sleep();
}
}
protected 受保护权限代码
package com.zgjy.demo1;
// 父类
public class Animal {
// 定义一个受保护权限的方法
protected void fun() {
System.out.println(“玩”);
}
}
package com.zgjy.demo;
import com.zgjy.demo1.Animal;
public class Cat extends Animal {
public void test() {
// 公共方法在外包的子类中可以使用
sleep();
// 受保护权限,在外包子类中可以使用
fun();
}
public static void main(String[] args) {
Cat c = new Cat();
c.test();
c.fun();
}
}
package com.zgjy.demo;
import com.zgjy.demo1.Animal;
public class Hello {
public static void main(String[] args) {
Cat c = new Cat();
// protected 受保护权限,封装的表现,可以在外包中子类内部使用
// protected 可以在本包中使用,在外包子类中,当成private使用
// c.fun(); 报错
}
}
默认权限代码
package com.zgjy.demo1;
// Person类使用了默认权限修饰,default (千万别写)
// 只能在本包中使用
class Person {
int i = 9 ;
public void eat() {
// 默认修饰的i,在本类中可以使用
i = 99;
System.out.println(i);
}
}
package com.zgjy.demo1;
public class Test {
public static void main(String[] args) {
// 默认修饰权限在本包中使用
Person p = new Person();
p.eat();
}
}
package com.zgjy.demo;
import com.zgjy.demo1.Animal;
public class Hello {
public static void main(String[] args) {
System.out.println(“Hello”);
// 默认权限只能在本包中使用
//Person p = new Person();
}
}