一.包
1什么是包?
(1)包是用来分别类的管理各种不同类的,类似于文件夹、建包利于程序的管理和维护。门
(2)建包的语法格式:package 公司域名倒写.技术名称。报名建议全部英文小写,且具备意义造
package com.heima.javabean;
public class Student {
}
(3)建包语句必须在第一行,一般IDEA工具会帮助创建
2导包
(1)相同包下的类可以直接访问,不同包下的类必须导包,才可以使用!
导包格式:import包名.类名;
(2)加入一个类中需要用到不同类,而这个两个类的名称都是一样的,那么默认只能导入一个类,另一个类要带包名访问。
package com.itheima_package;
//导包
import com.itheima_package.it.Student;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//目标:理解一下两点
//1同一个包下的类,互相可以直接访问
System.out.println(User.onlineNumber);
//2不同包下的类,必须先导包才可以访问
Student s = new Student();
Scanner sc = new Scanner(System.in);
//3如果这个类中使用不同包下的相同的类名,此时默认只能导入一个,另一个类要使用全名访问
com.itheima_package.it2.Student s2 = new com.itheima_package.it2.Student();
}
}
package com.itheima_package;
//导包。
import com.itheima_package.it.Student;
public class User {
public static int onlineNumber = 1234;
Student s = new Student();
}
package com.itheima_package.it;
public class Student {
}
package com.itheima_package.it2;
public class Student {
}
二.权限修饰符
1什么是权限修饰符?
(1)权限修饰符:是用来控制一个成员能够被访问的范围。
(2)可以修饰成员变量,方法,构造器,内部类,不同权限修饰符的成员能够被访问的范围将受到限制。
2权限修饰符的分类和具体作用范围:
(1)权限修饰符:有四种作用范围由小到大(private -> 缺省(没有修饰符) -> protected -> public)
修饰符 | 同一个类中 | 同一个包中其他类 | 不同包下的子类 | 不同包下的无关类 |
private | √ | |||
缺省 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
3学完权限修饰符需要具备如下能力
(1)能够识别别人定义的成员的访问范围
(2)自己定义成员(方法,成员变量,构造器等)一般需求满足如下要求:
(I)成员变量一般私有
(II)方法一般公开
(III)如果该成员只希望本类访问,使用private修饰
(IV)如果该成员只希望本类,同一个包下的其他类和子类访问,使用protected修饰
4总结
(1)权限修饰符是什么?
package com.itheima.d2_modifer;
public class Fu {
/**
* 1定义私有的成员:private 只能在本类中访问
*/
private void privateMethod(){
System.out.println("---private---");
}
/**
* 2定义缺省修饰的成员:只能本类或者同包下其他类访问(包访问权限)
*/
void method(){
System.out.println("--缺省--");
}
/**
* 3protected修饰方法:本类、同包的其他类中、其他包的子类中
*/
protected void protectedMethod(){
System.out.println("--protected--");
}
/**
* 4public修饰的方法:本类、同包的其他类,其他类的子类中,其他包的无关类中
*/
public void publicMethod(){
System.out.println("--public--");
}
public static void main(String[] arg){
Fu f = new Fu();
f.privateMethod();
f.method();
f.protectedMethod();
f.publicMethod();
}
}
package com.itheima.d2_modifer;
public class Test {
public static void main(String[] args) {
//目标:讲解权限修饰符的稀释范围,明白每一种修饰符修饰后的作用范围。
Fu f = new Fu();
//f.privateMethod;//报错,私有的
f.method();
f.protectedMethod();
f.publicMethod();
}
}
package com.itheima.d2_modifer.itcast;
import com.itheima.d2_modifer.Fu;
public class Zi extends Fu {
public static void main(String[] args) {
Zi zi = new Zi();
//zi.privateMethod;//
//zi.method();
zi.protectedMethod();
zi.publicMethod();
Fu f = new Fu();
f.publicMethod();
}
}
package com.itheima.d2_modifer.itcast;
import com.itheima.d2_modifer.Fu;
public class Test2 {
public static void main(String[] args) {
Fu f = new Fu();
//f.privateMethod;//报错,私有的
//f.method();//报错
//f.protectedMethod();//报错
f.publicMethod();
}
}
三.final
1final的作用
(1)final关键字是最终的意思,可以修饰(类、方法、变量)
(2)修饰类:表明该类是最终类,不能被继承。
(3)修饰方法:表明该方法是最终方法,不能被重写。
(4)修饰变量:表明该变量第一次赋值后,不能再次被赋值(有且仅能被赋值一次)
2final修饰变量的注意
(1)fianl修饰的变量是基本类型:那么变量存储的数据值不能发生改变。
(2)final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,但是地址指向的对象内容是可以发生变化的。
package com.itheima.d3_final;
public class Test {
public static void main(String[] args) {
//目标:记住final的语法。
//1final修饰类,类不能被继承
//2final修饰方法,方法不能被重写
//3final修饰变量,总规则:变量有且仅能被赋值一次
}
}
//class Wolf extends Animal{
//}
//final class Animal{
//}
class Student extends People{
// @Override
// public void eat(){
// System.out.println("学生吃的很多~~~");
// }
}
class People{
public final void eat(){
System.out.println("人都要吃东西~~~");
}
}
ackage com.itheima.d3_final;
public class Test2 {
/**
*二:修饰静态成员变量(public static final修饰的也称为常量)
*/
public static final String schoolName = "黑马";
/**
*三:修饰实例成员变量(几乎不用)
*/
private final String name = "猪刚烈";
public static void main(String[] args) {
//目标:理解final修饰变量的作用,总规则:变量有且仅能被赋值一次(理解语法)
//变量有几种
// 1.局部变量
// 2.成员变量
// --实例成员变量
// --静态成员变量
//一:修饰局部变量
final double rate = 3.14;
//rate = 3.19;//第二次赋值
buy(0.8);
//schoolName = "黑马程序员";//第二次赋值
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(String hobby) {
this.hobby = hobby;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
四.常量
1常量概述和基本作用
(1)常量
(I)常量是使用了public static final 修饰的成员变量,必须有初始化值,而且执行的过程中其值不能被改变
(II)常量的作用和好处:可以用于做系统的配置信息,方便程序的维护,同时提高可读性
public class Constant{
public static final String SHOOL_NAME = "传智教育";
public static final String LOGIN_NAME = "admin";
public static final String PASS_WORD = "123456";
}
常量命名规范:英文单词全部大写,多个单词下划线连接起来。
(2)常量的执行原理
(I)在编译阶段会进行“宏替换” ,把使用常量的地方全部替换成真实的字面量。
(II)这样做的好处是让使用常量的程序的执行性能与直接使用字面量是一样的。
2常量做信息标志和分类
(1)案例说明:现在开发的超级玛丽游戏需要接收用户输入的四个方向的信息(上下左右),以便控制玛丽移动的方向。
(2)选择常量做信息表示和分类:代码可读性好,实现了软编码形式
五.枚举
1枚举的概述
(1)枚举
(I)枚举是Java中的一种特殊类型
(II)枚举的作用:“是为了做信息的标志和信息的分类”
(2)定义枚举类的格式:
修饰符 enum 枚举名称{
第一行都是罗列枚举类实例的名称。
}
enum Season{
SPRING , SUMMER , AUTUMN , WINTER;
}
Compiled from "Season. java"
public final class Season extends java. lang. Enum<Season> {
public static final Season SPRING = new Season();
public static final Season SUMMER = new Season( );
public static final Season AUTUMIN = new Season( );
public static final Season WINTER = new Season();
public static Season[] values();
public static Season value0f(java . lang. String);
}
(3)枚举的特征:
(I)枚举类都是继承了枚举类型:java.lang.Enum
(II)枚举都是最终类,不可以被继承
(III)构造器的构造器都是私有的,枚举对外不能创建对象
(IV)枚举类的第一行默认都是罗列枚举对象的名称的
(VI)枚举类相当于是多例模式
2枚举的使用场景演示
(1)选择常量做信息标志和分类:虽然可以实现可读性,但是入参值不受约束,代码相对不够严谨。
(2)枚举做信息标识和分类:代码可读性好,入参约束严谨,代码优雅,是最好的信息分类计数!建议使用!
六.抽象类
1抽象类
(1)抽象类概述
(I)在Java中abstract是抽象的意思,可以修饰类、成员方法。
(II)abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
修饰符 abstract class 类名{
修饰符 abstract 返回值类型 方法名称(形参列表);
}
public abstract class Animal{
public abstract void run();
}
(2)注意事项
(I)抽象方法只有方法签名,不能声明方法体。
(II)一个类中如果定义了抽象方法,这个类必须声明成抽象类,否则报错。
(3)抽象的使用场景
(I)抽象类可以理解成不完整的设计图,一般作为父类,让子类来继承。
(II)当父类知道子类一定要完成某些行为,但是每个子类该行为的实现又不同,于是该父类就把该行为定义成抽象方法的形式,具体实现交给子类去完成。此时这个类就可以生命成抽象类。
public abstract class Animal{
public abstract void run();
}
(4)总结
(I)抽象类、抽象方法是什么样的?
(a)都是用abstract修饰的;抽象方法只有方法签名,不能写方法体。
(b)一个类中定义了抽象方法,这个类必须声明成抽象类。
(c)抽象类基本作用是啥?
(II)作为父类,用来被继承的。
(III)继承抽象类有哪些要注意?
(a)一个类如果继承了抽象类,那么这个类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
package com.itheima.d6_abstract;
/**
* 抽象类:有abstract修饰
*/
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;
}
}
package com.itheima.d6_abstract;
public class Dog extends Animal{
@Override
public void run() {
System.out.println("狗跑的贼快~~~");
}
}
package com.itheima.d6_abstract;
public class Test {
public static void main(String[] args) {
//目标:先认识抽象类,在了解它的使用场景。
Dog d = new Dog();
d.run();
}
}
2抽象的案例
(1)系统需求:
(I)某加油站推出了2中支付卡,一种是预存10000的金卡,后续加油可享受8折优惠,另一种是预存5000的银卡,后续加油享受8.5折优惠。
(II)请分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。
(2)分析实现
(I)创建一张卡片父类:定义属性包括主人名称、余额、支付功能(具体实现交给子类)
(II)创建一张白金卡类:重写支付功能,按照原价的8折计算输出
(III)创建一张银卡类:重写支付功能,按照原价的8.5折计算输出
package com.itheima.d7_abstract_test;
public abstract class Card {
private String name;
private double money;
/**
* 定义一个支付方法:表示卡片可以支付
* 抽象方法
*/
public abstract void pay(double money2);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
package com.itheima.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);
}
}
package com.itheima.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("您当前消费:" + money2);
System.out.println("您实际支付:" + rs);
//更新账户余额
setMoney(getMoney() - rs);
}
}
package com.itheima.d7_abstract_test;
public class Test {
public static void main(String[] args) {
//目标:学习一下抽象类的基本使用:做父类、被继承、重写抽象方法
GoldCard c = new GoldCard();
c.setMoney(10000);
c.setName("dlei");
c.pay(300);
System.out.println("剩余" + c.getMoney());
SilverCard s = new SilverCard();
s.setMoney(10000);
s.setName("马牛b");
s.pay(400);
System.out.println("剩余" + s.getMoney());
}
}
3抽象类的特征、注意事项小结
(1)类有的成员(成员变量、方法、构造器)抽象类都具备
(2)抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
(3)一个类继承了抽象类必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类
(4)不能用abstract修饰变量、代码块、构造器
(5)最重要的特征:得到了抽象方法,失去了创建对象的能力(有得有失)
4final和abstract是什么关系?
(1)互斥关系
(2)abstract定义的抽象类作为模板让子类继承,final定义的类不能被继承
(3)抽象方法定义通用功能让子类重写,final定义的方法子类不能重写
package com.itheima.d8_abstract_attention;
public class Test {
public static void main(String[] args) {
//目标:理解抽象类的特征和注意事项
//1类有的东西,抽象类都有
//2抽象类中可以没有抽象方法,但是有抽象方法的必须是抽象类
//3一个类继承了抽象类,必须重写完抽象类的全部抽象方法,否则这个类必须定义成抽象类
//4抽象类不能创建对象.为什么?
//反证法:加入抽象类可以创建对象,
//Animal a = new Animal();
//a.run();//run方法连方法体都没有!因此抽象类不能创建对象
//Card c = new Card();//不行,抽象类不能创建对象(这个观点不能动摇)
}
}
abstract class Card{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
abstract class Cat extends Animal{
@Override
public void run() {
}
//@Override
//public void eat() {
//}
}
abstract class Animal{
public abstract void run();
public abstract void eat();
}
4抽象类的应用知识:模板方法模式
(1)什么时候使用模板方法模式
(I)使用场景说明:当系统中出现同一个功能在多出开发,而该功能中大部分代码是一样的,只有其中部分可能不同的时候
(2)模板方法模式实现步骤
(I)把功能定义成一个所谓的模板方法,放在抽象类里,模板方法中只能定义通用且能确定的代码
(II)模板方法中不能决定的功能定义成抽象方法去让具体子类去实现
(3)理解模板方法:写作文案例
需求:(I)现有两类学生,一类是中学生,一类是小学生,他们都要写《我的爸爸》这篇作文。
(II)要求每种类型的学生,标题第一段和最后一段,内容必须一样。正文部分自己发挥
(III)请选择最优的面向对象方案进行设计。
(4)模板方法我们建议使用final修饰,这样会更专业,为什么?
答:模板方法是给子类直接使用的,不是让子类重写的,一旦子类重写了模板方法,则模板方法就失效了,因此,加上final后可以防止子类重写了模板方法,这样更安全、专业。
5总结
(1)模板方法模式解决了什么问题?
(I)提高了代码的复用性
(II)模板方法已经定义了通用结构,模板方法不能确定的部分定义成抽象方法,交给子类实现,因此,使用者只需要关心自己需要实现的功能即可。
package com.itheima.d9_abstract_template;
public abstract class Student {
/**
* 正式:声明了模板方法模式
*/
public final void write(){
System.out.println("\t\t\t\t《我的爸爸》");
System.out.println("你的爸爸是啥样,来说说");
//正文部分(每个子类都要写的,每个子类写的情况不一样
//因此,模板方法吧正文部分定义成抽象方法,交给具体子类完成
System.out.println(writemain());
System.out.println("我的爸爸简直是太好了!!!");
}
public abstract String writemain();
}
package com.itheima.d9_abstract_template;
public class StudentChild extends Student{
@Override
public String writemain() {
return "我的爸爸太nb了,他总是给我买东西吃。";
}
}
package com.itheima.d9_abstract_template;
public class StudentMiddle extends Student{
@Override
public String writemain() {
return "我爸爸也很牛,他开车都不看红绿灯的,下辈子还要做他儿子";
}
}
package com.itheima.d9_abstract_template;
public class Test {
public static void main(String[] args) {
//目标:理解模板方法模式的思想和使用步骤
StudentMiddle s = new StudentMiddle();
s.write();
}
}
接口
一.接口概述、特点
1接口的定义与特点
(1)接口的格式如下:
接口关键字interface来定义
public interface 接口名{
//常量
//抽象方法
}
2什么是接口
(1)接口也是一种规范
package com.itheima.d10_inteface;
/**
* 声明了一个接口:体现一种规范,规范一定是公开的
*/
public interface InterfaceDemo {
//目标:接口中的成分特点:JDK 8之前接口中只能有抽象方法和常量
//1常量
//注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract可以省略不写
String SHCOOL_NAME = "黑马程序员";
//public static final String SCHOOL_NAME = "黑马程序员";
//2抽象方法
//注意:由于接口体现规范思想,规范默认都是公开的,所以代码层面,public abstract可以省略不写
void run();
//public abstract void run();
void eat();
//public abstract void eat();
}
二.接口的基本使用:被实现
1接口的用法
(1)接口是用来被类实现(implements)的,实现接口的类成为实现类。实现类可以理解成所谓的子类。
修饰符 class 实现类 implements 接口1,接口2,接口3,...{
}
实现的关键字:implements
(2)从上面可以看出,接口可以被类单实现,也可以被类多实现
2实现接口的注意事项:
(1)一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类。
package com.itheima.d11_interface_implements;
public interface Law {
void rule();//遵纪守法
}
package com.itheima.d11_interface_implements;
/**
* 规范
*/
public interface SportMan {
void run();
void competition();
}
package com.itheima.d11_interface_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.itheima.d11_interface_implements;
public class Test {
public static void main(String[] args) {
//目标:理解接口的基本使用:被类实现
PingPongMan p = new PingPongMan("张继科");
p.run();
p.competition();
p.rule();
}
}
三.接口与接口的关系:多继承
1基本小结
(1)类和类的关系:单继承
(2)类和接口的关系:多实现
(3)接口和接口的关系:多继承,一个接口可以同时继承多个接口
2接口多继承的作用
(1)规范合并,整合多个接口为同一个接口,便于子类实现
package com.itheima.d12_interface_extends;
import com.itheima.d11_interface_implements.Law;
/**
* 一个实现类
*/
public class BasketBallMan implements SportMan {
@Override
public void eat() {
}
@Override
public void sleep() {
}
@Override
public void rule() {
}
@Override
public void run() {
}
@Override
public void competition() {
}
}
package com.itheima.d12_interface_extends;
public interface Law {
void rule();
}
package com.itheima.d12_interface_extends;
public interface People {
void eat();
void sleep();
}
package com.itheima.d12_interface_extends;
import com.itheima.d11_interface_implements.Law;
public interface SportMan extends Law , People {
void run();
void competition();
}
package com.itheima.d12_interface_extends;
public class Test {
public static void main(String[] args) {
//目标:理解接口多继承的作用。
}
}
四.JDK8开始接口新增方法
1第一种:默认方法
(1)类似之前写的普通实例方法:必须用default修饰
(2)默认会public修饰。需要用接口的实现类的对象来调用
default void run(){
System.out.println("--开始跑--");
}
2第二种:静态方法
(1)默认会public修饰,必须static修饰。
(2)注意:接口的静态方法必须用本身的接口名来调用。
static void inAddr(){
System.out.println("我们都在黑马培训中心快乐的学习Java!");
}
3第三种:私有方法
(1)就是私有的实例方法:必须使用private修饰,从JDK1.9才开始有的。
(2)只能在本类中被其他的默认方法或者私有方法访问。
private void go(){
System.out.println("--准备--");
}
4总结:
(1)JDK8开始后新增了哪些方法?
(I)默认方法:default修饰,实现类对象调用。
(II)静态方法:static修饰,必须用当前接口名调用。
(III)私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用
(IV)他们都会默认被public修饰
(V)JDK8新增的三种方法我们自己在开发中很少使用,通常是Java原码涉及到。现阶段需要理解、识别语法、明白调用关系即可。
package com.itheima.d13_interface_jdk8;
public interface SportManInter {
/**
* 1JDK 8开始:默认方法(实例方法)
* --必须是default修饰,默认用public修饰
* --默认方法,接口不能创建对象,这个方法只能过继给实现类,由实现类的对象调用
*/
default void run(){
go();
System.out.println("跑的很快~~~");
}
/**
* 2静态方法
* 必须使用static修饰,默认用public修饰
* --接口的静态方法,必须接口名自己调用
*/
static void inAddr(){
System.out.println("我们都在学习Java新增方法的语法,他是Java原码自己会用到的~~");
}
/**
* 3私有方法(实例方法)
* --JDK 1.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();
SportManInter.inAddr();
//PingPongMan.inAddr();
}
}
五.接口的注意事项
1接口不能创建对象
2一个类实现多个接口,多个接口中有同样的静态方法不冲突
3一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的
4一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可
5一个接口结成多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承
package com.itheima.d14.interface_attention;
public class Test {
public static void main(String[] args) {
//1接口不能创建对象(接口更加彻底的抽象,常识)
//2一个类实现多个接口,多个接口中有同样的静态方法不冲突
//3一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的
Cat c = new Cat();
c.eat();
//4一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可
//5一个接口结成多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承
}
}
//5一个接口结成多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承
interface AAA{
//int run();//有返回值
void run();//会合并
}
interface BBB{
void run();
}
interface CCC extends AAA,BBB{
}
//4一个类实现了多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可
interface AA{
default void go(){
System.out.println("AA");
}
}
interface BB{
default void go(){
System.out.println("BB");
}
}
class CC implements AA,BB{
@Override
public void go() {
}
}
//3一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的
interface Food{
default void eat(){
System.out.println("接口中的吃方法~~");
}
}
class Animal{
public void eat(){
System.out.println("父类动物吃~~");
}
}
class Cat extends Animal implements Food {
}
interface A{
static void test(){
System.out.println("A");
}
}
interface B{
static void test(){
System.out.println("B");
}
}
/**
* 2一个类实现多个接口,多个接口中有同样的静态方法不冲突.原因是接口的静态方法不能C调用,只能A调用A的,B调用B的
*/
class C implements A,B{
public static void main(String[] args) {
}
}
教育视频资源来自
Java入门基础视频教程,java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题)_哔哩哔哩_bilibili