第一章
1-1 什么类和对象:万物皆对象
1-2 定义Java中的类
步骤
- 定义类名
- 编写类的属性
- 编写类的方法
语法
public class 类名{//类名首字母大写
//定义属性
属性1
属性2。。。
//定义方法
方法1
方法2。。。
}
实例:
public class Telphone {
//属性
float screen;
float cpu;
//方法
public void call(){
System.out.println("打电话");
}
public void sendMessage(){
System.out.println("发短信");
}
}
1-3 如何使用java中的对象
步骤
- 创建对象
类名 对象名 = new 类名();
eg:Telphone phone = new Telphone(); - 使用对象
引用对象的属性:对象名.属性
eg:phone.screen = 5;
引用对象的方法:对象名.方法();
eg:phone.call();
1-5 Java中的成员变量和局部变量
- 成员变量:在类中定义,作用域在整个类内部都是可见的
- 局部变量:在类的方法中定义,作用域仅限于定义它的方法
PS:两类变量重名时,局部变量具有更高的优先级
1-6 Java中的构造方法
构造方法
- 使用new + 构造方法 创建一个新的对象
- 构造方法是定义在Java类中的一个用来初始化对象的方法*
- 构造方法与类同名且没有返回值
- 默认会自动创建一个无返回同名的方法
- 可以重载构造方法,根据参数的个数、类型、及顺序进行区别*
- 在类中自定义了构造方法,默认构造方法即不能直接实例化*
语法
public 构造方法名(参数1,参数2){//构造方法名即为类名
//初始代码
}
实例:
public Telphone(float newScreen){
screen = newScreen;//给属性赋值
}
1-7 Java中的static使用之静态变量
目的:所有类的对象共享一个成员
定义:被static修饰的成员称为静态成员或者类成员。
说明:
- 它属于整个类,而不是某个对象所有,即被类的对象所共享
- 静态变量可以直接使用类名访问,也可以使用对象名进行访问*,推荐使用类名访问
- 使用static可以修饰变量、方法和代码块
实例:
public class HelloWorld{
static String hobby = "shopping";
public static void main(String[] args){
System.out.println(HelloWorld.hobby);//直接类名.属性访问
HelloWorld hello = new HelloWorld();
System.out.println(hello.hobby)//使用类的对象访问静态变量
hello.hobby = "swimming";//静态变量赋值
}
}
1-9 Java中的static使用之静态方法
定义:被static修饰的方法称为静态方法或者类方法
实例:
public class HelloWorld{
public static void print(){//静态方法
System.out.print("打印");
}
public static void main(){
HelloWorld.print();//直接类名.方法()访问
HelloWorld hello = new HelloWorld();//通过类的对象访问
hello.print();
}
}
注意:
①静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员*
②普通成员方法中,可直接访问同类的非静态变量和静态变量
③静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法
④静态方法中可以通过类名.静态方法调用。
实例:
public class HelloWorld{
String name = "周";//非静态变量name
static String hobby = "shopping";//静态变量hobby
public static void print(){
System.out.println(name);//错误
System.out.println(hobby);//正确
HelloWorld hello = new HelloWorld();//静态方法中调用非静态属性
System.out.println(hello.name);
}
public void show(){//普通成员方法直接访问静态变量和非静态变量
System.out.println(name);
System.out.println(hobby);
}
public function call(){}
public static void main(String[] args){//静态方法中必须通过对象调用非静态方法
HelloWorld hello = new HelloWorld();
hello.call();
HelloWorld.print();//静态方法直接通过类名.静态方法调用
}
}
1-10 Java中的static使用之静态初始化块
实例:
public class HelloWorld{
String name;//定义一个成员变量
//通过初始化块为成员变量赋值
{
name = "zhou";
}
}
PS:在类的声明中可以包含多个初始化块;如果使用static修饰初始化块,则称为静态初始化块
注意:
①静态初始化块只在类加载时执行,且只会执行一次
②静态初始化块只能给静态变量赋值,不能初始化普通成员变量
实例:
public class HelloWorld{
int num1;//声明变量1
int num2;//声明变量2
static int num3;//声明静态变量3
public HelloWorld(){//构造方法
num1 = 91;
System.out.println("通过构造方法为变量num1赋值");
}
//初始化块
{
num2 = 72;
System.out.println("通过初始化块为变量num2赋值");
}
//静态初始化块
static {
num3 = 83;
System.out.println("通过静态初始化块为静态变量num3赋值");
}
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
System.out.println(hello.num1);
System.out.println(hello.num2);
System.out.println(num3);
System.out.println("=========");
HelloWorld hello2 = new HelloWorld();
}
}
输出结果:
通过静态初始化块为静态变量num3赋值
通过初始化块为变量num2赋值
通过构造方法为变量num1赋值
91
72
83
=========
通过初始化块为变量num2赋值
通过构造方法为变量num1赋值
总结:
①程序运行时静态初始化块最先被执行,然后普通初始化块,最后构造方法
②静态初始化块只在类加载时执行一次,所以当再次创建hello2对象时并未执行静态初始化块
第二章 封装
2-1 什么是java中的封装
面向对象的三大特性:封装、集成、多态。
封装:将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过类提供的方法来实现对隐藏信息的操作和访问。
优点:
①只能通过规定的方法访问数据
②隐藏类的细节,方便修改和实现
封装的实现步骤:
- 修改属性的可见性:private
- 创建getter/setter方法:用于属性的读写
- 在getter/setter方法中加入属性控制语句:对属性值合法性进行判读
实例:
public class HelloWorld{
private float screen;
public float getScreen() {
return screen;
}
public void setScreen(float newScreen) {
screen = newScreen;
}
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
hello.setScreen(20.1f);//属性赋值
float result = hello.getScreen();//获取属性值
System.out.println(result);
}
}
2-2 使用包管理java中的类
包的作用:
- 管理Java文件
- 解决同名文件冲突
定义包:
语法:package 包名;
必须放在Java源程序的第一行;包名可以使用”.”号隔开,如:com.jason.HelloWorld;HelloWorld为类名
实例:
com.jason.music.MyClassMusic;
com.jason.movie.MyClassMusic;
系统中的包:
- java.(功能).(类)
- java.lang.(类) 包含java语言基础的类
- java.util.(类) 包含java语言中的工具类
- java.io.(类) 包含输入、输出相关功能的类
包的使用:
- 通过import关键字,eg:import com.jason.music.MyClass;
- Java中,包的命名规范全是小写字母
- 使用的时候不但可以加载某个包下的所有文件,eg:com.jason.;也可以加载某个具体子包下的所有文件,eg:com.jason.music.;
实例:
package com.jason;
import com.jason.run.Telphone;
public class HelloWorld{
public static void main(String[] args) {
Telphone phone = new Telphone();//输出:我是com.jason.run包中的Telphone类
}
}
2-3 Java中的访问修饰符
作用:可以修饰属性和方法的访问范围.
总结:
访问修饰符 | 本类 | 同包 | 子类 | 其他 |
---|---|---|---|---|
public | T | T | T | T |
protected | T | T | T | |
默认 | T | T | ||
private | T |
2-4 Java中的this关键字
自动生成setter和getter方法:source->generate Getter and Setter…
实例:
package com.jason.wang;
public class Telphone {
private float screen;
public float getScreen() {
this.test();
return screen;
}
public void setScreen(float screen) {
this.screen = screen;
}
private void test() {
System.out.println("我是测试");
}
}
2-5 Java中的内部类
定义:定义在一个类里面的类,成为内部类;包含内部类的类成为外部类
作用:
- 内部类提供了更好的封装,可以将内部类隐藏在外部类之内,不允许同一个包中的其他的类访问该类
- 内部类的方法可以直接访问外部类的所有数据,包括私有的数据
- 内部类所实现的功能使用外部类同样可以实现,只是有时内部类使用更加方便
内部类的种类:
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
实例:
//外部类HelloWorld
public class HelloWorld {
// 内部类Inner,类Inner在类HelloWorld的内部
public class Inner {
// 内部类的方法
public void show() {
System.out.println("welcome to imooc!");
}
}
public static void main(String[] args) {
// 创建外部类对象
HelloWorld hello = new HelloWorld();
// 创建内部类对象
Inner i = hello.new Inner();
// 调用内部类对象的方法
i.show();
}
}
2-6 Java中的成员内部类
成员内部类也叫做普通内部类
成员内部类的使用方法:
- Inner类定义在Outer类的内部,相当于Outer类的一个成员变量的位置;Inner类可以使用任意访问控制符
- 定义了成员内部类后,必须使用外部类对象来创建内部类对象,即:内部类 对象名 = 外部类对象.new 内部类();
- 编译后生成两个.class文件,外部类Outer.class,内部类Outer 内部类名.class
注意:
①外部类不能直接访问内部类的成员或者方法,可通过内部类的对象来访问成员变量和方法
public class HelloWorld{
public class Inner{
public void show(){}
}
public void print(){
show();//错误,外部类不能直接访问内部类的方法
}
}
②如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或者方法,如果要访问外部类的成员变量,可以使用关键字this
//外部类
public class Outer {
private int a = 99;//外部类的私有属性
public class Inner{
int a = 2;//内部类的成员属性
public void test() {
System.out.println("访问外部类中的a:" + Outer.this.a);//99,,访问外部类中的成员属性
System.out.println("访问内部类中的a:" + a);//2
}
}
//测试成员内部类
public static void main(String[] args) {
Outer o = new Outer();//创建外部类对象
Inner i = o.new Inner();//使用外部类对象创建内部类对象
i.test();
}
}
2-7 Java中的静态内部类
定义:静态内部类是static修饰的内部类
说明:
- 静态内部类不能直接访问外部类的非静态成员,但可以通过new 外部类().成员的方式访问
- 如果外部类的静态成员和内部类的成员名称相同,可通过”类名.静态成员“访问外部类的静态成员
- 如果外部类的静态成员与内部类的成员名称不相同,可通过”成员名“直接调用外部类的静态成员
- 创建静态内部类的对象时,不需要外部类的对象,可以直接创建:内部类 对象名 = new 内部类();
实例:
public class Outer {
private int a = 99;//外部类的私有变量
static int b = 1;//外部类的静态变量
static int c = 10;
//静态内部类
public static class Inner{
int b = 2;//内部类的变量
public void test() {
System.out.println("访问外部非静态成员a:" + new Outer().a);//静态类通过new 外部类.成员访问外部非今静态成员
System.out.println("访问外部类的b:" + Outer.b);//外部静态成员和内部静态成员名称相同,"外部类名.成员"访问
System.out.println("访问内部类的b:" + b);
System.out.println("访问外部类不同名c:" + c);//外部类静态成员与内部类静态成员名称不相同,直接"成员名"访问
}
}
//测试成员内部类
public static void main(String[] args) {
Inner i = new Inner();//创建静态内部类的对象不需要外部类的对象
i.test();
}
}
2-8 Java中的方法内部类
定义:内部类定义在外部类的方法中。方法内部类只在该方法的内部可见,即只在该方法中可以使用
实例:
//外部类
public class Outer {
//外部类中的方法
public void show() {
final int A = 25;//常量
int b = 13;
//方法内部类
class Inner{
int c = 2;//内部类变量
public void print() {
System.out.println("访问外部类的方法中的常量A:" + A);
System.out.println("访问内部类中的变量c:" + c);
}
}
Inner i = new Inner();
i.print();
}
//测试成员内部类
public static void main(String[] args) {
Outer o = new Outer();
o.show();
}
}
注意:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和static修饰符
第三章 继承
3-1 Java中的继承
继承是类和类的一种关系。
Java中的继承是单继承。
好处:
- 子类拥有父类的所有属性和方法,属性和方法的修饰符不能是private
- 代码复用
语法:
class 子类 extends 父类{
}
实例:
class Dog extends Animal{}
Eclipse可以使用superclass选择需要继承的类
3-2 Java中方法的重写
语法规则:
- 返回值类型
- 方法名
- 参数类型和个数
- 前三者都要和父类继承的方法相同,才叫方法的重写
3-4 Java中的继承初始化顺序
顺序:
- 初始化父类再初始子类
- 先执行初始化对象中的属性,在执行构造方法中的初始化
- 流程:父类对象->父类属性初始化->父类构造方法->子类对象->子类属性初始化->子类构造方法
3-5 java中的final使用
- final 可以修饰类、方法、属性和变量
- final修饰类,则该类不允许被继承
- final修饰方法,则该方法不允许被覆盖(重写)
- final修饰属性,则该类的属性不能进行隐式的初始化。(类的初始化属性必须有值或者构造方法中赋值)
- final修饰变量,则该变量只能赋一次值,即为常量
语法:
final public class Animal{};
3-7 Java中的super的使用
super关键字:
在对象的内部使用,可以代表父类对象
①访问父类的属性
super.age
②访问父类的方法
super.eat();
实例:
public class Dog extends Animal {
int age = 20;
public void eat(){
System.out.println("狗具有吃东西的能力");
}
public void method() {
System.out.println(age);//子类属性
System.out.println(super.age);//父类属性
this.eat();//子类方法
super.eat();//父类方法
}
}
super的应用:
- 子类的构造的过程中必须调用其父类的构造方法
- 如果子类的构造方法中没有显式调用父类的构造方法,则系统默认调用父类无参数构造方法
- 如果显式的调用构造方法,必须在子类的构造方法的第一行
实例:
public Dog() {
super();//子类调用父类的构造方法,必须放在第一行,否则报错
System.out.println("Dog构造方法");
}
- 如果子类构造方法中既没有显式调用父类的构造方法,而父类中又没有无参的构造方法,则编译报错
3-8 Java中的Object 类I
Object类是所有类的父类,Object类中的方法,适合所有的子类
1. toString()方法
作用:返回对象的哈希code码(对象地址字符串)
可以通过重写toString()方法表示出对象的属性:source->generate toString()…
实例:
@Override
public String toString() {
return "Dog [age=" + age + "]";
}
public static void main(String[] args) {
Dog d = new Dog();
System.out.println(d);//输出:Dog [age=20],如果没重写toString()方法,则返回对象地址字符串:com.jason.Dog@33909752
}
3-9 Java中的Object类II
- equals()方法
作用:比较是对象的引用是否指向同一块内存地址
Dog dog = new Dog();//dog其实是对象的引用地址
实例:
Dog d = new Dog();
d.age = 10;
Dog d1 = new Dog();
d1.age = 15;
if(d.equals(d1)) {
System.out.println("两个对象是相同的");
}else {
System.out.println("两个对象是不同的");//输出
}
比较两个对象的值是否相同:重写equal()方法,source->generate hasCode and equals
实例:
@Override
public boolean equals(Object obj) {
if (this == obj)//两个引用的地址是否相同
return true;
if (obj == null)//有一个对象空值,地址为空,无需比较
return false;
/*
* obj.getClass() 类对象:姓名,年龄,身高,体重。。。
* obj 类的对象:阿宝,20岁,165cm,50kg
*
* */
if (getClass() != obj.getClass())//检测两个对象的类型是否相同
return false;
Dog other = (Dog) obj;
if (age != other.age)
return false;
return true;
}
public static void main(String[] args) {
Dog d = new Dog();
d.age = 15;
Dog d1 = new Dog();
d1.age = 15;
if(d.equals(d1)) {
System.out.println("两个对象是相同的");//输出
}else {
System.out.println("两个对象是不同的");
}
}
第四章 多态
4-1 Java中的多态
定义:对象的多种形态,继承是多态的基础
1.引用多态
- 父类的引用可以指向本类的对象
- 父类的引用可以指向子类的对象
实例:
Animal obj1 = new Animal();//父类的引用指向本类,两个Animal
Animal obj2 = new Dog();//父类的引用指向子类,前者Animal 后者Dog
//Dog obj3 = new Animal();//错误
2.方法多态
- 创建本类的对象时,调用的方法为本类的方法
- 创建子类对象时,调用的方法为子类重写的方法或者继承的方法
实例:
obj1.eat();//调用本类的方法
obj2.eat();//调用子类重写的方法或者继承的方法
4-2 多态中的引用类型转换
- 向上类型转换(隐式/自动类型转换),小类型=>大类型,无风险
- 向下类型装换(强制类型装换),大类型=>小类型,有风险
- instanceof运算符,解决对象的类型,避免类型装换的安全性问题
实例:
public static void main(String[] args) {
Dog dog = new Dog();
Animal animal = dog;//自动类型提升 向上类型装换
Dog dog2 = (Dog)animal;//向下类型装换 强制类型装换
//Cat cat = (Cat)animal;//错误,animal对象其实上面的dog对象;
//错误原因:编译时Cat类型 运行时Dog类型
//解决:
if(animal instanceof Cat) {
System.out.println("可以进行类型装换");
}else {
System.out.println("无法进行类型装换");
}
}
4-3 Java中的抽象类
定义:类前使用abstract关键字修饰,则该类为抽象类
应用场景:父类知道子类包含的方法,但不知道子类如何实现这些方法,约束子类
使用规则:
- abstract定义抽象类
- abstract定义抽象方法,只有声明,不需要实现
- 包含抽象方法的类为抽象类
- 抽象类中包含普通的方法,也可以没有抽象方法
- 抽象类不能直接创建,可以定义引用变量
- 抽象方法没有方法体,以分号结束
实例:
public abstract class Telphone {
public abstract void call();
public abstract void message();
}
4-5 Java中的接口
概念:类是一种具体的实现体,而接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部数据,也不关心这些类的方法实现细节,他只规定这些类必选提供某些方法
定义:interface关键字
语法:
[修饰符] interface 接口名 [extends 父接口1,父接口2...]{//[] 代表可选
零个到过个常量定义。。
零个到多个抽象方法定义。。。
}
接口就是用来被继承的,修饰符一般为public
使用接口:
一个类可以实现一个或者多个接口,实现接口使用implements关键字,Java中一个类只能继承一个父类,是不够灵活的,通过实现多个接口可以补充
继承父类实现接口的语法:
[修饰符] class 类名 extends 父类 implements 接口1 接口2...{
类体部分//如果继承了抽象类,需要实现继承的抽象方法;要实现接口中的抽象方法
}
实例:
public class SmartPhone extends Telphone implements IPlayGame{}
匿名类:没有名字的内部类,多用于关注实现而不关注实现类的名称
语法:
Interface i = new Interface(){
public void method(){
System.out.print("匿名内部类实现接口的方式");
}
};//注意分号
实例:
IPlayGame t5 = new IPlayGame(){
public void playGame() {
System.out.println("使用匿名内部类的方式实现接口");
}
};
t5.playGame();
或者:
new IPlayGame(){
public void playGame() {
System.out.println("使用匿名内部类的方式实现接口2");
}
}.playGame();
4-7 UML简介
定义:Unified Modeling Language(UML),统一建模语言或者标准建模语言,是一个支持模型化和软件系统开发的图形化语言
- 用例图:表达系统如何满足所收集的业务规则
- 序列图:显示对象之间的交互
- 类图:描述类和类的关系
常用建模工具:
Visio,Rational Rose,PowerDesign
第五章 阶段练习
5-1 阶段练习
public static void main(String[] args) {
//继承
Chinese p = new Chinese();
American a = new American();
p.say();
a.say();
//多态
APerson p1 = new Chinese();
APerson a1 = new American();
p1.say();
a1.say();
}
5-2 综合练习
Vehicle类:
package com.jason;
import java.util.Scanner;
public class Vehicle {
private String name;
private int rentingPDay;
private int PeopleCap;
private int cargoCap;
public Vehicle(String name,int rentingPDay,int peopleCap,int cargoCap){
setName(name);
setRentingPDay(rentingPDay);
setPeopleCap(peopleCap);
setCargoCap(cargoCap);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRentingPDay() {
return rentingPDay;
}
public void setRentingPDay(int rentingPDay) {
this.rentingPDay = rentingPDay;
}
public int getPeopleCap() {
return PeopleCap;
}
public void setPeopleCap(int peopleCap) {
PeopleCap = peopleCap;
}
public int getCargoCap() {
return cargoCap;
}
public void setCargoCap(int cargoCap) {
this.cargoCap = cargoCap;
}
}
DaDaMain类:
package com.jason;
import java.util.Scanner;
public class DaDaMain {
public static void main(String[] args) {
//定义一个带数字和字符串的数组
Vehicle vehicle[] = {new Vehicle("奥迪A4",500,4,0),
new Vehicle("马自达6",400,4,0),
new Vehicle("皮卡雪6",450,4,2),
new Vehicle("金龙",800,20,0),
new Vehicle("松花江",400,0,4),
new Vehicle("依维柯",1000,0,20)};
Scanner input = new Scanner(System.in);
int tog;//是否租车标志位
double sumCost = 0.0;
int vehicleNum = 0;//租车的数量
int dayOfRent = 0;
int peopleCapTotal = 0;
double cargoCapTotal = 0.0;
String nameOfVp="";
String nameOfVc="";
System.out.println("欢迎使用答答租车系统:");
System.out.println("您是否想租车:1 是 0 否");
tog = input.nextInt();
if(tog == 0) return;
System.out.println("您可租车的类型及价目表:");
System.out.println("序号 骑车名称 租金 容量");
for(int i=0;i<vehicle.length;i++) {
String result = (i) + " " + vehicle[i].getName() +
" " + vehicle[i].getRentingPDay() + "元/天";
if(vehicle[i].getPeopleCap() != 0) {
result += " " + vehicle[i].getPeopleCap() + "人";
}
if(vehicle[i].getCargoCap() != 0){
result += " " + vehicle[i].getCargoCap() + "吨";
}
System.out.println(result);
}
System.out.println("请输入您要租汽车的数量:");
vehicleNum = input.nextInt();
for(int k =0;k<vehicleNum;k++) {
System.out.println("请输入第" + (k+1) + "辆车的序号!" );
int j = input.nextInt();
sumCost +=vehicle[(j)].getRentingPDay();
if(vehicle[(j)].getPeopleCap() !=0) {
nameOfVp += vehicle[j].getName() + " ";
}
peopleCapTotal += vehicle[j].getPeopleCap();
if( vehicle[j].getCargoCap()!=0 ){
nameOfVc +=vehicle[j].getName() + " ";
cargoCapTotal += vehicle[j].getCargoCap();
}
}
System.out.println("请输入租车天数:");
int d = input.nextInt();
sumCost = sumCost * d;
System.out.println("您的账单:");
System.out.println("***可载人的车有:");
System.out.println(nameOfVp + " 共载人:"+ peopleCapTotal + "人");
System.out.println("***载货的车有:");
System.out.println(nameOfVc + " 共载货:"+ cargoCapTotal + "吨");
System.out.println("***租车总价格:" + sumCost);
input.close();
}
}