目录
一、包
什么是包:包是用来分门别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护
建包的语法格式:package 公司域名倒写.技术名称。包名建议全部英文小写,且具备意义
导包:相同包下的类可以直接访问,,不同包下的类必须导包,才可以使用。
导包格式:import 包名.类名
如果这个类中使用不同包下的相同类名,此时默认只能导入一个类的包,另外一个类要使用全名访问
二、权限修饰符
什么是权限修饰符:用来控制一个成员能被访问的范围
可以修饰成员变量,方法,构造器,内部类,不同的权限修饰符修饰的成员能被访问的范围会受到限制
权限修饰符的分类和具体作用范围:四种作用范围又小到大:private->缺省->protected->public
自己定义成员(成员变量、方法、构造器)一般需要满足:1.成员变量一般私有;2.方法一般公开;3.如果该成员只希望本类访问,使用private修饰;4.如果该成员只希望本类,同一个包下的其他类和子类访问,使用protected修饰
package com.pikaqiu.d2_modifier;
public class Fu {
/**
* 1.定义私有成员:private 只能本类中访问
*/
private void privateMethod(){
System.out.println("===private===");
}
/**
* 2.定义缺省修饰的成员:只能本类中、同包下其他类访问(包访问权限)
*/
void method(){
System.out.println("===缺省===");
}
/**
* 3.定义protected成员:protected 本类、同包的其他类中、其他包的子类中都可以访问
*/
protected void protectedMethod(){
System.out.println("===protected===");
}
/**
* 4.定义公共成员:public 本类、同包的其他类中、其他包的子类中、其他包的无关类中都可以访问
*/
public void publicMethod(){
System.out.println("===public===");
}
public static void main(String[] args) {
Fu f = new Fu();
f.privateMethod();
f.method();
f.protectedMethod();
f.publicMethod();
}
}
package com.pikaqiu.d2_modifier;
public class Test {
public static void main(String[] args) {
Fu f = new Fu();
//f.privateMethod(); //报错,非本类私有的无法访问
f.method();
f.protectedMethod();
f.publicMethod();
}
}
package com.pikaqiu.d2_modifier.picast;
import com.pikaqiu.d2_modifier.Fu;
public class Test2 {
public static void main(String[] args) {
Fu f = new Fu();
//f.privateMethod(); //报错,非本类私有的无法访问
//f.method(); //报错,非本类,不同包无法访问
//f.protectedMethod(); //报错,非本类、不同包的其他类中、也不是其他包的子类
f.publicMethod();
}
}
package com.pikaqiu.d2_modifier.picast;
import com.pikaqiu.d2_modifier.Fu;
public class Zi extends Fu {
public static void main(String[] args) {
Zi z = new Zi();
z.protectedMethod();
z.publicMethod();
Fu f = new Fu();
//f.protectedMethod();
f.publicMethod();
}
}
三、final
final关键字是最终的意思,可以修饰(类、方法、变量)
修饰类:表明该类是最终类,不能被继承;
修饰方法:表明该方法是最终方法,不能被重写;
修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)
注意:1.final修饰的变量是基本类型,那么变量存储的数据值不能发生改变;2.final修饰的变量是引用类型,那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以改变的
package com.pikaqiu.d3_final;
public class Test {
public static void main(String[] args) {
//1.修饰类:表明该类是最终类,不能被继承
//2.修饰方法:表明该方法是最终方法,不能被重写
}
}
class Student extends People{
// @Override
// public void eat(){
// System.out.println("学生吃的很多");
// }
}
class People{
public final void eat(){
System.out.println("人都要吃东西");
}
}
//final class Animal{
//
//}
//
//class Wolf extends Animal{
//
//}
package com.pikaqiu.d3_final;
public class Test2 {
//静态成员变量(public static final修饰的也称为常量)
public static final String SchoolName = "洛克王国";
//实例成员变量(几乎不用)
private final String name = "张三";
public static void main(String[] args) {
//3.修饰变量:表示该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)
//变量有两种:1.局部变量;2.成员变量--实例成员变量和静态成员变量
//局部变量
final double rate = 3.14;
//rate = 3.19; //错误,不能二次赋值
buy(0.8);
//SchoolName = "hhh"; //错误,不能第二次赋值
Test2 t = new Test2();
System.out.println(t.name);
//t.name = "李四"; 错误,不能二次赋值
//注意:final修饰的变量是引用类型,那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以改变的
final Teacher t2 = new Teacher("学习");
//t2 = null;
System.out.println(t2.getHobby());
t2.setHobby("运动");
System.out.println(t2.getHobby());
}
public static void buy(final double z){
//z = 0.1; //错误,形参传入时已经赋值了
}
}
class Teacher{
private String hobby;
public Teacher() {
}
public Teacher(String hobby) {
this.hobby = hobby;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
四、常量
1.常量概述和基本作用
常量是使用了public static final修饰的成员变量,必须有初始化值,而且执行的过程中其值不能被改变
常量的作用和好处:可以用于做系统的配置信息,方便程序的维护,同时也能提高可读性
常量的命名规范:英文单词全部大写,多个单词下划线连接起来
常量的执行原理:1.在编译阶段会进行宏替换,把使用常量的地方全部替换成真实的字面量;2.这样做的好处是让使用常量的程序的执行性能与直接使用字面量是一样的
2.常量做信息标志和分类
好处:代码可读性好,实现了软编码形式
五、枚举
1.枚举的概述
枚举是Java中的一种特殊类型
枚举的作用:是为了做信息的标志和信息的分类
定义枚举的格式:修饰符 enum 枚举名称{第一行都是罗列枚举类实例的名称}
枚举的特征:1.枚举类都是继承了枚举类型:java.lang.Enum;2.枚举都是最终类,不可以被继承;3.枚举类的构造器都是私有的,枚举对外不能创建对象;4.枚举的第一行默认都是罗列枚举对象的名称的;5.枚举类相当于是多例模式
2.枚举的使用场景演示
选择常量做信息标志和分类:虽然可以实现可读性,但是入参值不受约束,代码相对不够严谨
枚举做信息标志和分类:代码可读性好,入参约束严谨,代码优雅,是最好的信息分类技术,建议使用
六、抽象类
1.抽象类
在Java中abstract是抽象的意思,可以修饰类、成员方法
abstract修饰类,这个类就是抽象类;abstract修饰方法,这个方法就是抽象方法
注意事项:1.抽象方法只有方法签名,不能声明方法体;2.一个类中如果定义了抽象方法,这个类必须声明成抽象类
抽象类的使用场景:1.抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承;2.当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成,此时这个类就可以声明为抽象类
继承抽象类需要注意:一个类如果继承了抽象类,那么这个类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
package com.pikaqiu.d6_abstract;
//抽象类
public abstract class Animal {
//抽象方法,不能写方法体代码
public abstract void run();
}
package com.pikaqiu.d6_abstract;
public class Dog extends Animal{
@Override
public void run() {
System.out.println("狗跑的很快~~~");
}
}
package com.pikaqiu.d6_abstract;
public class Test {
public static void main(String[] args) {
Dog d = new Dog();
d.run();
}
}
2.抽象类的应用案例
package com.pikaqiu.d7_abstract_test;
public abstract class Card {
private String userName;
private double money;
//定义一个支付方法,表示卡片可以支付(抽象方法)
public abstract void pay(double money2);
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;
}
}
package com.pikaqiu.d7_abstract_test;
public class GoldCard extends Card{
@Override
public void pay(double money2) {
System.out.println("您当前消费:" + money2);
System.out.println("您卡片当前余额:" + getMoney());
double rs = money2 * 0.8;
System.out.println("您实际支付:" + rs);
//更新余额
setMoney(getMoney() - rs);
System.out.println("支付后的余额:" + getMoney());
}
}
package com.pikaqiu.d7_abstract_test;
public class SilverCard extends Card{
@Override
public void pay(double money2) {
System.out.println("您当前消费:" + money2);
System.out.println("您卡片当前余额:" + getMoney());
double rs = money2 * 0.85;
System.out.println("您实际支付:" + rs);
//更新余额
setMoney(getMoney() - rs);
System.out.println("支付后的余额:" + getMoney());
}
}
package com.pikaqiu.d7_abstract_test;
public class Test {
public static void main(String[] args) {
GoldCard c = new GoldCard();
c.setMoney(10000);
c.setUserName("皮卡丘");
c.pay(300);
System.out.println("------------------");
SilverCard s = new SilverCard();
s.setMoney(5000);
s.setUserName("妙蛙种子");
s.pay(300);
}
}
3.抽象类的特征、注意事项
1.类有的成员(成员变量、方法、构造器)抽象类都具备
2.抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
3.一个类如果继承了抽象类,那么这个类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
4.不能用abstract修饰变量、代码块、构造器
最重要的特征:得到了抽象方法,失去了创建对象的能力
抽象类为什么不能创建对象:假设抽象类可以创建对象,但是当该对象调用方法时,该方法连方法体都没有,很显然是矛盾的。而且java是很严谨的,不完整的设计图实例化就可能出现问题,为了避免问题,索性直接规定死。
final和abstract是什么关系:互斥关系。abstract定义的抽象类作为模板让子类继承,否则没有意义,final定义的类不能被继承;抽象方法定义通用功能让子类重写,final定义的方法子类不能重写
4.抽象类的应用知识:模板方法模式
使用场景说明:当系统中出现同一个功能多处在开发,而功能中大部分代码是一样的,只有其中部分可能不同的时候
模板方法模式实现步骤:1.把功能定义成一个所谓的模板方法,放在抽象类中,模板方法中只定义通用且确定的代码;2.模板方法中不能决定的功能定义成抽象方法让具体子类去实现
模板方法建议使用final修饰:模板方法是给子类直接使用的,不是让子类重写的,一旦子类重写了模板方法,则模板方法就失效了,因此,加上final后可以防止子类重写了模板方法,这样更安全、专业。
package com.pikaqiu.d9_abstract_template;
public abstract class Student {
//声明模板方法
public final void write(){
//标题
System.out.println("《童年》");
//开头
System.out.println("池塘边的榕树上");
//正文部分(每个子类都要写,但是每个子类的写情况不一样)
System.out.println(writeMain());
//结尾
System.out.println("盼望长大的童年");
}
public abstract String writeMain();
}
package com.pikaqiu.d9_abstract_template;
public class StudentChild extends Student{
@Override
public String writeMain() {
return "操场边的秋千上,还有蝴蝶停在上面";
}
}
package com.pikaqiu.d9_abstract_template;
public class StudentMiddle extends Student{
@Override
public String writeMain() {
return "只有知了声声叫着夏天";
}
}
package com.pikaqiu.d9_abstract_template;
public class Test {
public static void main(String[] args) {
StudentMiddle s1 = new StudentMiddle();
s1.write();
System.out.println("--------------------------");
StudentChild s2 = new StudentChild();
s2.write();
}
}
七、接口
1.接口概述、特点
接口的格式如下:public interface 接口名{//常量 //抽象方法}
什么是接口:接口是一种规范
package com.pikaqiu.d10_interface;
/**
* 声明一个接口:体现一种规范,规范一定是公开的
*/
public interface InterfaceDemo {
//1.常量
//注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public static final可以省略不写
String SCHOOL_NAME = "妖怪学院";
//public static final String SCHOOL_NAME = "妖怪学院";
//2.抽象方法
//注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract可以省略不写
void run();
//public abstract void run();
void eat();
//public abstract void eat();
}
2.接口的基本使用: 被实现
接口的用法:接口是用来被类实现的,实现接口的类称为实现类。实现类可以理解成所谓的子类
格式:修饰符 class 实现类 implements 接口1,接口2,接口3,...{}
注意:1..接口可以被类单实现,也可以被类多实现;2.一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义为抽象类
package com.pikaqiu.d11_implements;
public interface SportMan {
void run();
void competition();
}
package com.pikaqiu.d11_implements;
public interface Law {
void rule();
}
package com.pikaqiu.d11_implements;
public class PingPongMan implements SportMan,Law{
private String name;
public PingPongMan(String name){
this.name = name;
}
@Override
public void run() {
System.out.println(name + "必须跑步训练");
}
@Override
public void competition() {
System.out.println(name + "必须参加比赛");
}
@Override
public void rule() {
System.out.println(name + "必须遵纪守法");
}
}
package com.pikaqiu.d11_implements;
public class Test {
public static void main(String[] args) {
PingPongMan p = new PingPongMan("张继科");
p.run();
p.competition();
p.rule();
}
}
3.接口与接口的关系:多继承
类和类的关系:单继承;类和接口的关系:多实现;接口和接口的关系:多继承,一个接口可以同时继承多个接口
接口多继承的作用:规范合并,整合多个接口为同一个接口,便于子类实现
4.JDK8开始接口新增方法
第一种:默认方法
1.类似之前写的普通实例方法:必须用default修饰;2.默认会public修饰,需要用接口的实现类的对象来调用
第二种:静态方法
1.默认会public修饰,必须使用static修饰;2.注意:接口的静态方法必须使用本身的接口名来调用
第三种:私有方法
1.就是私有的实例方法:必须使用private修饰,从JDK1.9才开始有的;2.只能在本类中被其他的默认方法或者私有方法访问
package com.pikaqiu.d13_interface_jdk8;
public interface SportManInter {
//1.默认方法
//必须default修饰,默认public修饰
//这个方法只能过继给实现类,由实现类的对象调用
default void run(){
System.out.println("跑的很快~~~");
// go();
}
//2.静态方法
//必须使用static修饰,默认public修饰
//接口的静态方法,必须使用接口名自己调用
static void inAdd(){
System.out.println("学习Java新增方法的语法");
}
//3.私有方法
//JDK1.9开始支持
//必须在接口内部才能被访问
// private void go(){
// System.out.println("开始跑~~~");
// }
}
class PingPongMan implements SportManInter{
}
class Test{
public static void main(String[] args) {
PingPongMan p = new PingPongMan();
p.run();
//p.go();
SportManInter.inAdd();
//PingPongMan.inAdd();
}
}
5.使用接口的注意事项
1.接口不能创建对象(接口更加彻底的抽象);
2.一个类实现多个接口,多个接口中有同样的静态方法不冲突;
3.一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的;
4.一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可;
5.一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承