包
- 包是用来分门别类的管理各种不同类的,类似于文件夹,建包利于程序的管理和维护
- 建包的语法格式:package 公司域名倒写.技术名称。包名建议全部英文小写,且具备意义
- 建包语句必须在第一行,一般idea工具会帮助创建
导包
- 相同包下的类可以直接访问,不同包下的类必须导包才可以使用,import 包名.类名;
- 自动导包设置
Perferences/Settings->输入auto出现自动导包
- 类中使用不同包下的相同类名,此时默认只能导入一个类的包,另一个类要使用全名访问
package com.echo.d1_package;
import com.echo.d1_package.it.Person;
public class demo1 {
public static void main(String[] args) {
System.out.println(Student.OnLineNumber);
System.out.println(Person.Number);
com.echo.d1_package.it1.Person person = new com.echo.d1_package.it1.Person();
System.out.println(person);
}
}
package com.echo.d1_package.it;
public class Person {
public static int Number=100;
}
package com.echo.d1_package.it1;
public class Person {
}
package com.echo.d1_package;
public class Student {
public static int OnLineNumber=100;
}
![请添加图片描述](https://img-blog.csdnimg.cn/135638bf881a403b874eca41e0a82167.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVmlsbGFuZWxsZVM=,size_20,color_FFFFFF,t_70,g_se,x_16)
权限修饰符![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/72b01f0b1a56f0cd296e3f9dc48f8369.png)
final
final的作用
- final关键字是最终的意思,可以修饰类、方法、变量
- 修饰类:表明该类是最终类,不能被继承
- 修饰方法:表明该方法是最终方法,不能被重写
- 修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)
final修饰变量的注意
- final修饰的变量是基本类型,那么变量存储的数据值不能发生改变
- final修饰的变量是引用类型,那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的
public class Test {
public static void main(String[] args) {
final Teacher t1 = new Teacher();
// t1=null; //第二次赋值报错
t1.setName("张三");
System.out.println(t1.getName());
}
}
class Teacher{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
常量
- 常量是使用了public static final修饰的成员变量,必须有初始化值,而且执行过程中其值不能被改变
- 常量的作用和好处:可以用于做系统的配置信息,方便程序的维护,同时也能提高可读性
- 常量命名规范:英文单词全部大写,多个单词用下划线连接起来
常量的执行原理
- 在编译阶段会进行”宏替换“,把使用常量的地方全部替换成真实的字面量
- 让使用常量的程序的执行性能与直接使用字面量是一样的
public class usefinalmean {
public static final String SCHOOL_NAME="西安中学";
public static final String USER_NAME="root";
public static final String PASS_WORD="123456";
public static void main(String[] args) {
System.out.println(SCHOOL_NAME);
System.out.println(SCHOOL_NAME);
System.out.println(USER_NAME);
System.out.println(PASS_WORD);
}
}
案例
现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号(上下左右),以便控制玛丽移动的方向
public class ConstantDemo1 {
public static final String UP_DIRECT="up";
public static final String DOWN_DIRECT="down";
public static final String LEFT_DIRECT="left";
public static final String RIGHT_DIRECT="right";
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String action = sc.next();
if(UP_DIRECT.equals(action)){
System.out.println("向上走");
}else if(DOWN_DIRECT.equals(action)){
System.out.println("向下走");
}else if(LEFT_DIRECT.equals(action)){
System.out.println("向左走");
}else if(RIGHT_DIRECT.equals(action)){
System.out.println("向右走");
}
}
}
枚举
- 枚举是Java中的一种特殊类型
- 枚举的作用:为了做信息的标志和信息的分类
枚举的特征
- 枚举类都是继承了枚举类型:java.lang,Enum
- 枚举都是最终类,不可以被继承
- 构造器的构造器都是私有的,枚举对外不能创建对象
- 枚举类的第一行默认都是罗列枚举对象的名称的
- 枚举类相当于是多例模式
public enum Season {
SPRING,SUMMER,AUTUMN,WINTER;
}
案例
现在开发的超级玛丽游戏需要接收用户输入的四个方向的信号(上下左右),以便控制玛丽移动的方向
public class Test {
public static void main(String[] args) {
move(Direct.UP);
move(Direct.DOWN);
move(Direct.LEFT);
move(Direct.RIGHT);
}
public static void move(Direct o){
switch(o){
case UP:
System.out.println("向上飞");
break;
case DOWN:
System.out.println("向下蹲");
break;
case LEFT:
System.out.println("向左走");
break;
case RIGHT:
System.out.println("向右走");
break;
}
}
}
抽象类
抽象类的概述
- Java中abstract是抽象的意思,可以修饰类、成员方法
- abstract修饰类。这个类就是抽象类,修饰方法,这个方法就是抽象方法
注意事项
- 抽象方法只有方法签名,不能声明方法体
- 一个类中如果定义了抽象方法,这个类必须声明成抽象类,否则报错
- 一个类如果继承了抽象类,那么这个类必须重写抽象类的全部抽象方法,否则这个类也必须定义成抽象类
抽象类的使用场景
- 抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承
- 当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成,此时这个类就可以声明成抽象类
public abstract class Animal { //抽象方法
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Animal(String name) {
this.name = name;
}
public abstract void run(); //抽象类
}
public class Dog extends Animal{
public Dog(String name){
super(name);
}
public Dog() {
super("笨笨");
}
public void run(){
System.out.println("名字叫:"+super.getName()+",狗跑的贼快");
}
}
public class Test{
public static void main(String[] args) {
Dog d=new Dog("奇奇");
d.run();
Dog d1=new Dog();
d1.run();
}
}
案例
系统需求
某加油站推出了2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,一种是预存5000的银卡,后续加油享受8.5折优惠
请分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能
分析实现
- 创建一张卡片父亲:定义属性包括主人名称,余额,支付功能(具体实现交给子类)
- 创建一张白金卡类:重写支付功能,按照原价的8折计算输出
- 创建一张银卡类:重写支付功能,按照原价的8.5折计算输出
public abstract class Card {
private String name; //用户名称
private double money; //用户余额
private double zhe; //用户折扣
public double getZhe() {
return zhe;
}
public void setZhe(double zhe) {
this.zhe = zhe;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void pay(double paymoney); //抽象类
}
public class GoldCard extends Card {
public GoldCard(){
setMoney(10000);
setZhe(0.8);
}
@Override
public void pay(double paymoney) {
setMoney(this.getMoney()-paymoney*this.getZhe());
}
}
public class SilverCard extends Card {
public SilverCard(){
setMoney(5000);
setZhe(0.85);
}
@Override
public void pay(double paymoney) {
setMoney(this.getMoney()-paymoney*this.getZhe());
}
}
public class demo1 {
public static void main(String[] args) {
GoldCard user1 = new GoldCard();
user1.setName("张三");
System.out.println(user1.getName()+"用户的余额是:"+user1.getMoney());
user1.pay(3000);
System.out.println(user1.getName()+"用户的余额是:"+user1.getMoney());
SilverCard user2=new SilverCard();
user2.setName("李四");
System.out.println(user2.getName()+"用户的余额是:"+user2.getMoney());
user2.pay(3000);
System.out.println(user2.getName()+"用户的余额是:"+user2.getMoney());
}
}
抽象类的特征、注意事项小结
- 类有的成员(成员变量、方法、构造器)抽象类都具备
- 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
- 一个类继承了抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
- 不能用abstract修饰变量,代码块、构造器
- 最重要的特征:得到了抽象方法,失去了创建对象的能力
final和abstract是互斥关系
抽象类的应用知识:模版方法模式
当系统中出现同一个功能多处在开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候
模版方法模式实现步骤
把功能定义成一个所谓的模版方法,放在抽象类中,模版方法中只定义通用且能确定的代码
模版方法中不能确定的功能定义成抽象方法让具体子类去实现
案例:写作文案例
需求
- 现有两类学生,一类是中学生,一类是小学生,他们都要写《我的爸爸》这篇作文
- 要求每种类型的学生,标题第一段和最后一段,内容必须一样。正文部分自己发挥
- 请选择最优的面向对象方案进行设计
public abstract class Student {
public final void write(){ //模版方法
System.out.println("\t\t\t\t\t\t\t《我的爸爸》");
System.out.println(" 我有一个好爸爸。");
writeMain();
System.out.println(" 我爱我的爸爸。");
}
public abstract void writeMain();
}
public class StudentMiddle extends Student{
@Override
public void writeMain() {
System.out.println(" 我的爸爸是一个教授,我每天的作业他都辅导我");
}
}
public class StudentSmall extends Student{
@Override
public void writeMain() {
System.out.println(" 我的爸爸是一个生意人,但是他不论多晚都会每天都会回家哄我睡觉");
}
}
public class Test2 {
public static void main(String[] args) {
StudentSmall s1 = new StudentSmall();
s1.write();
System.out.println();
StudentMiddle m1 = new StudentMiddle();
m1.write();
}
}
模版方法要使用final修饰的
模版方法是给子类直接使用的,不是让子类重写的。一旦子类重写了模版方法,则模版方法就失效了,因此,加上final后可以防止子类重写了模版方法,这样更安全,专业