目录
前言:
一、包
二、权限修饰符
三、final关键字
四、常量
五、枚举
六、抽象类
七、抽象类:模板方法模式
八、接口
①包:
在编写Java程序时,随着程序架构越来越大,类的个数也越来越多,这时就会发现管理程序中维护类名称也是一件很麻烦的事,尤其是一些同名问题的发生。有时,开发人员还可能需要将处理同一方面的问题的类放在同一个目录下,以便于管理。
为了解决上述问题,Java 引入了包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突、类文件管理等问题。
包允许将类组合成较小的单元(类似文件夹),它基本上隐藏了类,并避免了名称上的冲突。包允许在更广泛的范围内保护类、数据和方法。你可以在包内定义类,而在包外的代码不能访问该类。这使你的类相互之间有隐私,但不被其他世界所知。
包的 3 个作用如下:
②final 关键字表示对象是最终形态的,对象是不可改变的意思。
③枚举:
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。 [1] 是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。
④抽象类:
Java语言中,用abstract 关键字来修饰一个类时,这个类叫作抽象类。抽象类是它的所有子类的公共属性的集合,是包含一个或多个抽象方法的类。抽象类可以看作是对类的进一步抽象。在面向对象领域,抽象类主要用来进行类型隐藏。
⑤接口:
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
两种含义:
一,Java接口,Java语言中存在的结构,有特定的语法和结构;
二,一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做“Java接口”,后者叫做“接口”。
1.概念:
包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护。
2.导包:
想同包下的类可以直接访问,不同包下的类必须导包,才可以使用!导包格式:import 包名.类名;
3.注意:
①同一个包下的类,互相可以直接访问;
②不同包下的类,必须先导包才可以访问;
③如果这个类中使用不同包下的相同的类名,此时默认只能导入一个类的包,另一个类要使用全名访问;
1.概念:
①权限修饰符是用来控制一个成员能够被访问的范围。
②可以修饰成员变量,方法,构造器,内部类,不同权限修饰符修饰的成员能够被访问的范围将受到限制。
2.权限修饰符的分类和具体作用范围:
权限修饰符:有四种作用范围由小到大(private >缺省 >protected >public).
3.代码演示:
父类:
public class Fu {
private void privatemethod(){
//1、定义私有成员,private 只能在本类访问
System.out.println("-------private------------");
}
void method(){
//2、定义缺省修饰的成员: 只能在本类、同包下其他类访问(包访问权限)
System.out.println("-----缺省-------");
}
protected void protectedmethod(){
//3、protected 修饰的方法,本类,同包的其它类中,其他包的子类中
System.out.println("--------protected-------");
}
public void publicmethod(){
//public修饰的方法中,本类,同包的其它类中,其他包的子类中,其他包的无关类中。
System.out.println("----------public---------");
}
public static void main(String[] args) {
Fu f = new Fu();
f.privatemethod();
f.method();
f.protectedmethod();
f.publicmethod();
}
}
子类:
public class Zi extends Fu{
public static void main(String[] args) {
Zi zi = new Zi();
zi.method();
zi.protectedmethod();
zi.publicmethod();
Fu f =new Fu();
f.publicmethod();
f.protectedmethod();
f.method();
}
}
4.学完权限修饰符需要具备以下能力:
①能够识别别人定义的成员的访问范围;
②自己定义成员(方法,成员变量,构造器等)一般需要满足如下要求:
③成员变量一般私有;方法一般公开;
④如果该成员只希望本类访问,使用private修饰;
⑤如果该成员只希望本类,同一个包下的其它类和子类访问,使用protected修饰;
1.final的作用:
①final关键字是最终的意思,可以修饰(类,方法,变量)。
②修饰类:表明该类是最终类,不能被继承。
③修饰方法:表明该方法是最终方法,不能被重写。
④修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)。
2.final修饰变量的注意:
①final修饰的变量是基本类型:那么变量存储的数据值不能发生改变;
②final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。
3.变量分为:
1、局部变量
2、成员变量
--实例成员变量
--静态成员变量
public class final_Demo {
// 二、修饰静态成员变量
public static final String schoolName = "黑马";
//三、修饰实例变量
private final String name = "猪刚烈";//几乎不用
public static void main(String[] args) {
// 一、修饰局部变量
final double rate = 3.14;
buy(0.8);
//schoolName = "九歌" 报错,第二次赋值失败
final_Demo5 t = new final_Demo5();
System.out.println(t.name);
//t.name = "天蓬元帅";报错 ,不能修改
}
public static void buy(final double z){
//z = 0.1; //第二次赋值失败
}
}
1.概述:
①常量是使用public static final 修饰的成员变量,必须有初始值,而且执行过程中其值不能被改变。
②作用和好处:可以用作系统的配置信息,方便程序的维护,同时提高可读性
③命名规范:英文单词全部大写,多个单词下划线连接起来
2.常量的执行原理 :
①在编译阶段会进行"宏替换",把使用常量的地方全部替换成真是的字面量。
②这样做的好处是让使用常量的程序的执行性能与直接使用字面量是一样的。
3.代码演示:
/*
常量
*/
public class A {
public static final String SCHOOL_NAME = "XXX有限公司";
public static void main(String[] args) {
System.out.println(SCHOOL_NAME);
System.out.println(SCHOOL_NAME);
System.out.println(SCHOOL_NAME);
System.out.println(SCHOOL_NAME);
}
}
4.案例:
案例说明:
①开发的超级玛丽游戏需要接受用户输入的四个方向的信号(上下左右),以便控制玛丽移动的方向。
②选择常量做信息标志和分类:
③代码可读性好,实现了软编码形式。
代码演示:
import javax.swing.*;
import java.awt.event.ActionEvent;
/*
常量
*/
public class A {
public static final int UP =1;//上
public static final int DOWN =2;//下
public static final int LEFT =3;//左
public static final int RIGHT =4;//右
public static void main(String[] args) {
//1.创建一个窗口对象(桌子)
JFrame win = new JFrame();
//2.创建一个面板对象(桌布)
JPanel jPanel = new JPanel();
//3.把桌布垫在桌子上
win.add(jPanel);
//4.创建四个按钮对象
JButton btn1 = new JButton("上");
JButton btn2 = new JButton("下");
JButton btn3 = new JButton("左");
JButton btn4 = new JButton("右");
//5.把按钮对象添加到桌布上去
jPanel.add(btn1);
jPanel.add(btn2);
jPanel.add(btn3);
jPanel.add(btn4);
//6.显示窗口
win.setLocationRelativeTo(null);
win.setSize(300,400);
win.setVisible(true);
btn1.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e){
move(UP);
}
});
btn2.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e){
move(DOWN);
}
});
btn3.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e){
move(LEFT);
}
});
btn4.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e){
move(RIGHT);
}
});
}
public static void move(int flag){
//控制玛丽移动
switch (flag){
case UP:
System.out.println("玛丽向上跳一下");
break;
case DOWN:
System.out.println("玛丽向下蹲一下");
break;
case LEFT:
System.out.println("玛丽向左跑一下");
break;
case RIGHT:
System.out.println("玛丽向右跑一下");
break;
}
}
}
1.概述:
①枚举是Java中一种特殊的类型
②枚举的作用:是为了做信息的标志和信息的分类
2.定义枚举类的格式 :
修饰符 enum 枚举名称{
第一行都是罗列枚举实例的名称
}
enum Season{
SPRING,SUMMER,AUTUMN,WINTER;
}
3.代码演示:
public enum enum_Demo {
//枚举类 第一行必须罗列枚举类的对象名称,建议全部大写
SPRINT, SUMMER, AUTUMN, WINTER;
}
4.枚举的特征:
①枚举类都是继承了枚举类型 :java.lang.Enum;
②枚举类都是最终类,不可以被继承;
③枚举类构造器都是私有的·,枚举对外不能创建对象;
④枚举类的第一行都是罗列枚举对象的名称的;
⑤枚举类相当于是多例类型;
⑤枚举做信息标志和分类:
代码可读性好,入参约束严谨,代码优雅,是最好的信息分类技术!
1.概述
①在java中abstract是抽象的意思,可以修饰类,成员方法。
②abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
2.代码格式:
3.使用场景:
①抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承。
②当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以声明成抽象类。
/**
* 抽象类(abstract)
* abstract 修饰类,这个类就是抽象类;修饰方法就是抽象方法
* 一般作为父类,让子类继承(当父类知道子类一定要完成某些行为,
* 但每个子类的实现方式不同,于是父类就把该行为定义成抽象方法的形式,
* 具体实现交给子类去完成,这个类就可以声明称抽象类
*/
public abstract class abstract_Demo6 {//抽象类
public static void main(String[] args) {
}
public abstract void run ();//抽象方法
}
/**
*1、 类有的东西,抽象类都有
* 2、抽象类中可以没有抽象方法,但由抽象方法的必须是抽象类
* 3、一个类继承了抽象方法,它必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
* 4、不能用abstract修饰变量、代码块、构造器
* 特征:抽象类不能创建创建对象 。 为什么?
*/
/**final和abstract是互斥关系
*final修饰类 不能被继承 方法不能被重写
* abstract修饰类 必须要被继承 方法必须被重写
*/
/**抽象类设计模板方法模式 :提高了代码的复用性
* 当系统中出现同一个功能多处开发,而功能中大部分代码是一样的,只有其中部分可能不同
*/
4.代码演示:
动物父类:
public abstract class Animal {
private String name;
//抽象方法:有abstract修饰,不能写方法体代码
public abstract void run();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
狗子类:
public class Dog extends Animal {
@Override
public void run(){
System.out.println("狗跑的贼快~~");
}
}
实现main类:
public class abstract_Test {
public static void main(String[] args) {
//抽象类使用场景
Dog d = new Dog();
d.run();
}
}
5.抽象类的基本作用是什么?
作为父类,用来被继承的。
6.继承抽象类需要注意什么?
一个类继承了抽象方法,它必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
7.案例:
需求:
①某加油站推出的2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,另一种是预存5000的银卡,后续加油享受8.5折的优惠。
②分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。
分析:
①创建一张卡片父类:定义属性包括主人名称,余额,支付功能(具体实现交给子类)。
②创建一张白金卡类:重写支付功能,按照原价的8折计算输出。
③创建一张银卡类:重写支付功能,按照原价的8.5折计算输出。
卡片父类:
public abstract class Card {
private String username;
private double money;
/*
定义一个支付方法,表示卡片可以支付。
抽象方法
*/
public abstract void pay(double money);
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Card{" +
"username='" + username + '\'' +
", money=" + money +
'}';
}
}
白金卡类:
public class GoldCard extends Card{
@Override
public void pay(double money) {
System.out.println("您当前消费:"+money);
System.out.println("您卡片当前余额为:"+getMoney());
//优惠计算
double rs = money *0.8;
System.out.println("您实际支付了"+rs);
//更新账户余额
setMoney(getMoney() - rs);
}
}
银卡类:
public class WriteCard extends Card {
@Override
public void pay(double money) {
System.out.println("您当前消费:"+money);
System.out.println("您卡片当前余额为:"+getMoney());
//优惠计算
double rs = money *0.85;
System.out.println("您实际支付了"+rs);
//更新账户余额
setMoney(getMoney() - rs);
}
}
main类:
/*抽象类案例
需求:
①某加油站推出的2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,另一种是预存5000的银卡,后续加油享受8.5折的优惠。
②分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。
*/
public class Test {
public static void main(String[] args) {
GoldCard g = new GoldCard();
g.setMoney(10000);
g.setUsername("张三");
g.pay(300);
System.out.println("剩余:"+g.getMoney());
System.out.println("---------");
WriteCard w = new WriteCard();
w.setMoney(5000);
w.setUsername("李四");
w.pay(400);
System.out.println("剩余:"+w.getMoney());
}
}
结果:
8.抽象类的特征和注意事项:
①类有的东西,抽象类都有;
②抽象类中可以没有抽象方法,但有抽象方法的必须是抽象类; ③一个类继承了抽象方法,它必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类;
④不能用abstract修饰变量、代码块、构造器。
⑥最重要的特征:抽象类不能创建对象。
9.final和abstract是什么关系?
①互斥关系;
②final修饰类 不能被继承 方法不能被重写;
③abstract修饰类 必须要被继承 方法必须被重写。
1.使用场景说明:
当系统中出现同一个功能多处开发,而功能中大部分代码是一样的,只有其中部分可能不同。
2.模板方法模式实现步骤:
①把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且能确定的代码。
②模板方法中不能决定的功能定义成抽象方法让具体子类去实现。
3.抽象类设计模板方法模式 作用 :
提高了代码的复用性
4.案例:写作文案例
需求:
①现在有两类学生,一类是中学生,一类是小学生,他们都要写《我的爸爸》这篇作文。
②要求每种类型的学生,标题第一段和最后一段,内容必须一样。正文部分自己发挥。
③请选择最优的面向对象方案进行设计。
学生类:
public abstract class Student {
/*
声明了模板方法模式
*/
public void write() {
System.out.println("\t\t\t\t《我的爸爸》");
System.out.println("你的爸爸是啥样的,来说说");
/*正文(每个子类都要写的,每个子类的情况都不一样,
因此,模板方法把正文部分定义成抽象方法,交给具体的子类去完成)
*/
System.out.println(writeMain());
System.out.println("我的爸爸简直是太好了");
}
public abstract String writeMain();
}
中学生类:
public class StudentMiddle extends Student{
@Override
public String writeMain() {
return "我的爸爸很喜欢隔壁的王阿姨~~";
}
}
小学生类:
public class StudentChild extends Student{
@Override
public String writeMain() {
return "我的爸爸开车从来不看红绿灯!!";
}
}
实现main类:
/*案例:
抽象类:模板方法模式
*/
public class Test2 {
public static void main(String[] args) {
StudentMiddle s = new StudentMiddle();
s.write();
System.out.println("-------------");
StudentChild c = new StudentChild();
c.write();
}
}
代码结果:
5.模板方法建议使用final修饰,这样更专业,为什么?
模板方法是给子类直接使用的,不让子类重写的,一旦子类重写了模板方法,则模板方法就失效了,因此,加上final后可以防止子类重写了模板方法,这样更安全,专业。
6.模板方法解决了什么问题?
①提高了代码的复用性;
②模板方法已经定义了通用结构,模板方法不能确定的部分定义成抽象方法,交给子类实现,因此,使用者只需要关心自己需要实现的功能即可。
1.接口的定义与特点?
接口的格式:
接口只能写常量和抽象方法。
public interface 接口名{
//常量
//抽象方法
}
public interface interface_Demo {
//1、常量
public static final String scoolName = "CC程序员";
final String scoolName = "CC程序员";
//2、抽象方法
void run();
void eat();
public abstract void run();
public abstract void eat();
}
注意: 接口体现规范思想,规范默认都是公开的,所以代码public abstract可以省略不写
2.接口的用法:
①接口是用来被类实现的,实现接口的类被称为实现类。实现类可以理解成所谓的子类。
②可以单继承,也可以多继承 接口和接口可以多继承
修饰符 class implements 接口1 ,接口2,接口3{
}
3.代码演示:
运动员接口:
public interface SportMan {
/*
规范
*/
void run();
void competition();
}
乒乓球员子接口:
public class PingpongMan implements SportMan {
private String name;
public PingpongMan(String name) {
this.name = name;
}
@Override
public void run(){
System.out.println(name+"必须进行跑步训练");
}
@Override
public void competition() {
}
}
实现接口:
public class Test {
public static void main(String[] args) {
//接口
PingpongMan p = new PingpongMan("张继科");
p.run();
p.competition();
}
}
4.接口的注意事项:
①一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类。
1、接口不能创建对象(接口更加彻底的抽象)
2、一个类实现多个接口,多个接口中有同样的静态方法不冲突
3、一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的
4、一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可
5、一个接口继承多个接口,是没有问题的如果多个接口中存在规范冲突则不能多继承。
5.小结:
①类和类之间的关系:单继承
②类和继承之间的关系:多实现
③接口和接口之间的关系:多继承,一个接口可以同时继承多个接口。
6.接口的多继承:
一个接口可以同时继承多个接口;
7.代码演示:
SportMan类:
public interface SportMan {
/*
规范
*/
void run();
void competition();
}
Law类:
public interface Law {
void rule();
}
Perple类:
public interface Perple {
void sleep();
}
实现类:
/*
接口的多继承
*/
public class Test2 implements Law,SportMan,Perple{
@Override
public void rule() {
}
@Override
public void run() {
}
@Override
public void competition() {
}
@Override
public void sleep() {
}
}
8.允许接口中直接定义带有方法体的方法。
①默认方法(实例方法)
必须default修饰;
默认用public修饰,需要用接口的实现类的对象来调用。
default void runs(){
System.out.println("跑得很快");
}
②静态方法
必须使用static修饰,默认会用public修饰;
注意:接口的静态方法,必须用本身的接口名来调用。
static void inAddr(){
System.out.println("java新增的语法,Java源码会用到");
}
③私有方法 就是私有的实例方法:必须使用private修饰,从JDK1.9才开始有的。
只有在本类中被其他的默认方法或者私有方法访问。
private void go(){
System.out.println("开始跑");
}
8.JDK8开始后新增哪些方法?
①默认方法:default修饰,实现类对象调用;
②静态方法:static修饰,必须用当前接口名调用;
③私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。
④他们都会默认被public修饰。
9.使用接口的注意事项:
①接口不能创建对象(接口更加彻底的抽象);
②一个类实现多个接口,多个接口中有同样的静态方法不冲突;
③一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的;
④一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可;
⑤一个接口继承多个接口,是没有问题的如果多个接口中存在规范冲突则不能多继承。