一、JAVA第一阶段学习内容与方法
1.1 学习内容
专业高级阶段的5个核心内容:
第一个阶段是Java核心语言。
分三个小阶段:
Java语言基础
Java面向对象
Java语言高级
1.2 学习目标
分成二个层次
第一个层次:必须掌握:OOP 能写。基本语法。能看懂。
第二个层次:提高理解:OOA&D 会写。必须在理解的基础。
OOP:Object Oriented Programming (面向对象编程) 编码阶段codding
OOA: Object-Oriented Analysis(面向对象分析) 是确定需求或者业务的角度,按照面向对象的思想来分析业务。
OOD: Object-Oriented Design (面向对象设计) 面向对象设计是OO方法中⼀个中间过渡环节。主要作用是对OOA结果作进⼀步的规范化整理,以便能够被oop直接接收
1.3 学习方法
1 基本语法,必须背。必须 掌握。
2 软件设计方向,OOAD。理解。想。为什么?
脑子要动起来。想为什么。
二、对比面向过程与面向对象
面向过程和面向对象都是编写应用程序的一种方法。
2.1 区别
面向过程是一种以过程(方法)为最小颗粒度的编程语言。
一个方法一旦声明完成,这个方法的功能就不能改变了。
面向对象是一种以过程中使用的对象为最小颗粒度的编程语言。
一个方法声明完成,会根据使用的对象的不同,而改变这个方法的功能。
2.2 案例:盖房子
不管面向过程,还是面向对象,实现功能都需要有相应的业务逻辑。
盖房子:打地基 -> 砌墙 -> 封顶 这是一个固定的步骤。
(1) 面向过程语言
打四方地基( ){ },打圆地基( ){ }
砌四方墙( ){ },砌圆墙( ){ }
封平顶( ){ }
盖房子A( ){
打四方地基();
砌四方墙();
封平顶();
}
盖房子B( ){
打圆地基();
砌圆墙();
封平顶();
}
问:盖房子A这个方法,每调用一次,输出的结果一定是一个四方的房子。
面向过程语言,一个方法一旦编写完成,功能就固定了。想要一个不同功能的方法就只能新编写一个。
(2) 面向对象语言
面向对象语言,最小的颗粒度是过程实现过程中使用到的对象。
面向对象语言中第一件事是找对象。
先找到打地基,砌墙和封顶的对象。
封装
class 打地基类{ void 打地基(); }
继承
class 打四方地基类 extends
打四方地基对象
class 打圆地基类 extends
打圆地基对象
class 打五角地基类 extends
打五角地基对象
同一个盖房子的方法。
盖房子(打地基类 打地基对象,,){
打地基对象.打地基( );
}
多态
调用时,使用不同的对象做为参数。同一个方法在执行完成之后,可以得到不同的结果。
盖房子(打四方地基对象,,); -? 多态
盖房子(打圆地基对象,,); -? 多态
三、类和对象(语法)
3.1 关系
类和对象之间的关系。必须是从现实世界向软件世界转换的过程。
现实世界--------------->软件世界
现实中的对象---(具有相同性质的对象抽象,抽出属性和行为)--->类-----(实例化)------>对象(软件世界)
3.2 创建类(语法)
类Class是一个特殊的数据类型。与int,String本质是一样的。
类中有属性和方法。 例如:学员,手机这些数据类型。
属性:就是变量。
方法:就是我们之前编写的方法。 public static void print(int i);
创建的基本语法:class就是类的关键字。
public class 类名{
}
public class A{
}
3.3 创建对象(语法)
类是一种特殊的数据类型。使用这个类型创建的变量也称为叫对象。
所以使用类创建一个对象时,需要使用new关键字进行实例化。
对象就可以通过打点的方式,调用类型中的属性和方法。
对象名.属性;
对象名.方法();
变量的使用规则 :
1 先声明
int i;
A a;
2 初始化
i = 10;
a = new A();
3 使用
sout(i);
a.属性=值;
sout(a.属性);
a.方法();
int x = a.方法();
class A {
int i = 10;
public void print(){
System.out.println("这是A类中的一个叫print方法");
}
}
public class Test01 {
public static void main(String[] args) {
//使用A类创建对象a
A a = new A();
a.i = 40;
System.out.println(a.i);
a.print();
}
}
3.4 专用名词
A a = new A();
a 我们叫引用。
new A(); new是实例化,实例化:在内存中创建实例空间的过程。 实例。
实例:就是我们内存中开辟的空间。
3.5 对象的内存结构
a为储存在调用方法中的一个引用,new A();则是申请一片空间来储存A中属性和方法。
3.6 属性
属性 : 一般都是指在类中声明的变量,称为成员变量,成员属性。
针对成员属性,我们也叫实例属性。
成员属性:就是在类中发声明的变量。
成员属性的作用域: 是受访问修饰符影响的。属性一般使用private。
private 表示私有。类内私有。表示属性只在声明的这个类中可以使用。
3.7 方法(语法)
方法:成员方法,实例方法。在类中声明的方法。
成员方法的作用域: 方法一般使用public。
public 表示公有。任意位置都可以使用。
成员方法可以用来操作成员属性
3.8 JavaBean的规范
一个类如果按JavaBean规范编写,应该具备如下三个要求:
1 默认构造方法
2 私有属性
3 公有set/get方法
set和get方法的命名格式规范:
set和get做前缀,将属性名的首字母大写拼接。
class A {
private int age = 10;//成员属性。私有的。可以在本类的任意位置使用。
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class B {
public static void main(String[] args){
A a = new A();
//a.age = 24;
/*由于age是A类的私有变量,所以不可以通过对象来直接访问,
但是可以通过A类中的方法来访问*/
a.setAge(24);
System.out.println(a.getAge());
}
}
3.9 this 关键字
this是我们Java代码中的一个关键字。
this是在实例内部一个指向自身实例的引用。
我们使用this可以指定本类中的属性和方法。
3.10 实例属性和实例方法是属于实例的
每一个实例都有自己的实例属性和实例方法。
每new一次都是开辟一个新空间,各个空间的属性方法互不影响。
四、类和对象(软件设计)
4.1 类是怎么来的
类是什么?
类是对现实世界中具有相同属性和相同方法的大量对象的抽象,并抽取相同的属性和方法。
抽象的将得到的属性和发方法使用 {} 封装起来。使用关键字 class +名称 组成类。
例如:
class A{
属性;
方法
}
现实世界对象是 “万物解对象” 所有可以被描述的事物都是对象。
例如:我们做一个学员管理系统。
对现实世界中大量的学员对象,进行抽象,抽属性和方法。
类是模板
学员类{
学号;
姓名;
睡觉();
打游戏();
}
/**
* 这是一个学员类
*/
public class Stu {
//有学号
private int sid;
//有姓名
private String sname;
//有睡觉的方法
public void sleep(int hours){
System.out.println(this.sname + "晚上休息了 "+hours+" 小时!");
}
4.2 对象
类是模板
手机,学员,笔记本电脑。
对象是具体的事物。
我手下的键盘,我的同桌,我的手机。
4.3 练习:编写如下的类
1.编写手机类
public class Phone {
private String brand;
private int price;
private String color;
}
2.编写汽车类
public class Car {
//品牌
private String type;
//价格
private int price;
//跑
public void run(int distance){
System.out.println(this.type+"加满油能跑"+distance+"公里");
}
3.编写狗类
public class Dog {
// 编号
private int id;
// 品种
private String type;
// 年龄
private int age;
// 性别
private String gender;
public void sleep(){
System.out.println("狗会睡觉");
}
public void eat(){
System.out.println("狗吃骨头");
}
public void call(){
System.out.println("汪汪汪");
}
}
五、构造方法
构造方法也是一个方法
在类中一个特殊的方法
5.1 什么是构造方法
一个与类同名的,并没有返回类型描述的方法,叫构造方法。
public class Stu {
//构造方法
public Stu(){
System.out.println("构造方法!");
}
}
5.2 构造方法的分类
构造方法有如下几种分类:
1 默认构造方法:一个没有参数的构造方法。
隐式构造方法:当一个类没有编写构造方法时,系统会自动为这个提供一个默认构造方法。
2 参数化构造方法:有参数的构造方法。
tips:每一个类都有一个自己的构造方法。(一定有!就算不写jdk也会给一个隐是够在方法)
5.3 构造方法的作用
构造方法是在对象被实例化时调用的方法。
在创建实例的过程中一定要调用构造方法来创建我们的对象。
构造方法不用我们指定。系统会根据new关键字后面的类的格式来调用对应的构造方法。
Stu s1 = new Stu();//new关键字时一定要调用构造方法。
系统会按Stu()来调用对应的构造方法。
构造方法的作用是在实例化时为类的属性进行初始化操作。
class Stu {
//有学号
private int sid;
//有姓名
private String sname;
//有参构造
public Stu(int sid, String sname) {
this.sid = sid;
this.sname = sname;
}
}
public class Main {
Stu s1 = new Stu(1,"张三");//new关键字时一定要调用构造方法。
}
案例:学生信息
这是先写的两个类,其中birthday是stu中的一个属性。
class Birthday {
private int year;
private int month;
private int day;
public Birthday() {
}
public Birthday(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
//set&get
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
@Override
public String toString() {
return "Birthday{" +
"year=" + year +
", month=" + month +
", day=" + day +
'}';
}
}
class Stu {
//有学号
private int sid;
//有姓名
private String sname;
//出生日期
private Birthday birthday ;//被构造方法初始化的属性
//构造方法
public Stu(){
System.out.println("构造方法!");
birthday = new Birthday();
}
//有参构造
public Stu(int sid, String sname) {
this.sid = sid;
this.sname = sname;
birthday = new Birthday();
}
public Stu(int sid, String sname,int year, int month, int day){
this.sid = sid;
this.sname = sname;
birthday = new Birthday(year,month,day);
}
}
private static void demo1() {
//第一种
Stu stu = new Stu();
stu.setName("张三");
stu.setBirthday(2000,1,12);
stu.getBirthday().setDay(1000);
System.out.println(stu.birthday.toString());
//第二种
Birthday birthday = new Birthday(2000,1,2);
stu.setBirthday(birthday);
System.out.println(stu.birthday.toString());
}
上述的两种赋值方式都是新开辟空间后赋值,所以两个空间并不相同,以至于不会互相影响。
六、对象创建的过程(扩展)
Stu s = new Stu(); //一个对象创建的完整过程包含二个部分 类加载 和 对象创建
对象创建过程的步骤:实例化-初始化-引用赋值
1 实例化:内存中开辟实例(Stu),并为每一个属性赋默认值。
2 初始化:调用相应的构造方法(Stu()),来完成对属性的初始化。
3 引用赋值:将实例的引用赋值给引用(s)。
七、面向对象的三大特性:封装
封装:在Java中{ }就是封装。
if(条件){
代码 //被封装的代码
}
封装的例子有很多,大到类小到方法无处不在。
类是对大量对象进行抽象,抽象出相同的属性和方法,将属性和方法进行封装形成类。
方法是对代码的封装。
封装的好处:
1 隐藏代码细节。使用方法时,只关心格式和作用。不关心代码实现。
2 模块化开发。可同时开发且复用率高
九、继承(语法)
9.1 继承的关键字
extends!!!!
9.2 继承的格式
继承一定二个类之间的关系。
格式:
public class 子类 extends 父类{
}
注意!!!!
在Java中只支持单继承。一个类只能有一个直接父类。
每个人只能有一个爹!!! 类也一样
class A{
}
public class B extends A{
}
9.3 继承之后的好处
子类可以使用父类的属性和方法。
子类可以使用父类所有的属性和方法。
只不过,当属性使用private修饰时,表示私有。
父类中声明的私有属性和方法,可以继承,但是不能使用。
9.4 继承关系的实现方式是什么
在Java中继承关系的实现方式: 是以为每一个子类实例配置一个其父类的实例。并使用super这个引用,从子类实例中指向父类实例。
B b = new B(); //new B(); 是要创建一个B类的实例。在创建B类实例时,发现B有父类A。就会再创建一个A类的实例。
内存展示如图:
9.5 创建两个实例(父类和子类的实例)时是先后顺序
根据上面的图。我们发现。创建子类实例时,也一定会创建一个父类实例。
实例的创建过程。一定要调用类的构造方法。
父类与子类之间的实例的创建顺序:先创建好父类实例,再创建好子类实例。
父类与子类构造方法的调用顺序:先调用子类构造方法,在子类构造方法的第一行调用父类构造方法。
示例代码:
class A {
private int i;
public A() {
System.out.println("A类默认构造方法!");
}
public void print(){
System.out.println("A.print()");
}
}
public class B extends A{
public B() {
System.out.println("B类默认构造方法!");
}
public static void main(String[] args) {
B b = new B();
b.print();//调用父类的方法。
}
}
输出结构:
A类默认构造方法!
B类默认构造方法!
A.print()
9.6 this 和super
this是一个在实例内部指向其自身实例的引用。
super是一个在子类实例内部指向其父类实例的引用。
(1) this
就三种用法
1 this() 在构造方法内部引用自身其他构造方法的格式。
2 this.属性 调用自身属性的格式
3 this.方法() 调用自身方法的格式
(2) super
就三种用法
1 super() 在子类构造方法的第一行,调用父类构造方法的格式。
2 super.属性 调用父类属性的格式
3 super.方法() 调用父类方法的格式。一般这个格式会在方法重写中出现。
示例代码:
class A {
private int i;
public A() {
System.out.println("A类默认构造方法!");
}
public A(int i){
this.i = i;
System.out.println("A类有参构造方法!");
}
public void print(){
System.out.println("A.print()");
}
}
public class B extends A{
public B() {
System.out.println("B类默认构造方法!");
}
public B(int i){
super(i);//向父类构造方法传参
System.out.println("B类有参构造方法!");
}
public static void main(String[] args) {
B b = new B();
b.print();//调用父类的方法。
B b1 = new B(10);
}
}
9.7 方法重写
方法重写:在父类与子类有相同的方法。这二个方法就叫方法重写。
class A {
public void print(){
System.out.println("A.print()");
}
}
public class B extends A{
public void print(){
System.out.println("B.print()");
}
//在子类(B)中重写了父类(A)继承过来的print方法。
}
当子类调用被重写的方法时,就近原则:先找到哪一个方法就调用哪一个方法
(1) 检查方法是否重写的注解
注解:当@Override报红就表示重写代码有问题
@Override
public void print(){
super.print();//调用父类的print()方法。
System.out.println("B.print()");
}
(2) 方法重载
方法重载:同类同名不同参
例如:println()这个方法
同类:同一个类中可以使用的方法。 不是同一个类中声明的方法。(子类从父类继承的方法就可以重载)
9.8 练习
1. 编写父类(Person)
有属性:姓名;
有方法:喊到(){
sout("大家好!我是XXXX");
}
2. 编写子类(Student)
有属性:学号和姓名;
有方法:喊到(){
sout("大家好!我是XXXX");
sout("我的学号是XXX!");
}
class Person {
private String name;
public Person(){
}
public Person(String name) {
this.name = name;
}
public void call(){
System.out.println("大家好!我是"+this.name);
}
}
public class Student extends Person{
private int sid;
public Student() {
}
public Student(String name, int sid) {
super(name);
this.sid = sid;
}
@Override
public void call(){
super.call();
System.out.println("大家好!我是"+this.getSid());
}
}
public static void main(String[] args) {
Student s1 = new Student();
s1.setSid(1);
s1.setName("张三");
s1.call();
}
十、面向对象语言三大特点:继承(软件工程)
10.1 父类是怎么来的
(1) 父类的概念:
类是对大量对象的抽象。
父类对大量子类的抽象。抽的是相同的属性和方法。
(2) 子类和父类的区别
父类中保存了所有子类共性的属性和方法。
子类中自己的特性的属性和方法。
父类更通用。子类更具体。
10.2 继承的使用时机
当我们发现有很多的类,有相同的属性和方法,就可以考虑使用继承。
10.3 类的继承
(1) 判断条件:
is-a 是一个。
必须满足 子类 是 一个父类。 子类 is-a 父类
(2) 类之间的关系
1 is-a 是一个 继承 子类是一个父类
2 has-a 有一个 组合 类的属性
3 use-a 用一个 依赖 方法的参数
(3) 示例
把下面的四个类的关系整理清楚:
司机 车 BMW 发动机
关系:
BMW is-a 车
车 has-a 发动机
司机 use-a 车
class 司机{
public void 工作(车 车对象){
车对象.跑();
}
}
class 车{
private 发动机 发动机对象;
}
class BMW extends 车{
}
class 发动机{
}
10.4 何时使用方法重写
当发现从父类继承的方法,在子类中不适用时。就可以在子类中对这个方法进行重写操作。
10.5 继承和方法重写的意义
在面向对象语言特性中:封装,继承,多态是三大特性。
其中封装和继承都是为了实现多态服务的。
封装的目的是为了能获到类,属性,方法。
继承的目的是在不修改源文件的情况下,可以实现对功能的修改。
依据"开放-封闭"原则:对扩展开放,对修改关闭。
所以当有一个类,中的方法需要进行更新时。我们应该扩展一个子类。在子类中重写这个方法。
继承和方法重写真正的目的是在不修改源文件的情况,扩展一个子类,实现对父类的修改。
十一、练习:员工分类
Employee类
Employee:这是所有员工总的父类,
属性:员工的姓名(name),员工的生日月份(month)。
方法:double getSalary(int month) 根据参数月份来确定工资,如果该月员工过生日,则公司会额外奖励10000元。
实现代码:
public class Employee {
private String name;
private int month;
public Employee() {
}
public Employee(String name, int month) {
this.name = name;
this.month = month;
}
/**
* 计算员工当月工资的方法
* @param month 发工资的月份
* @return 如果当月员工过生日就返回10000。否则返回0
*/
public double getSalary(int month){
if(this.month == month){
return 10000;
}else{
return 0;
}
}
}
SalariedEmployee类
SalariedEmployee:Employee的子类,拿固定工资的员工。
属性:月薪(monthlySalary)
实现代码:
public class SalariedEmployee extends Employee{
private double monthlySalary;
public SalariedEmployee() {
}
public SalariedEmployee(String name, int month, double monthlySalary) {
super(name, month);
this.monthlySalary = monthlySalary;
}
@Override
public double getSalary(int month) {
return super.getSalary(month)+this.monthlySalary;
}
}
HourlyEmployee类
HourlyEmployee:Employee的子类,按小时拿工资的员工,每月工作超出160小时的部分按照1.5倍工资发放。
属性:每小时的工资(hourlySalary)、每月工作的小时数(hours)
实现代码:
public class HourlyEmployee extends Employee{
private double hourlySalary;
private int hours;
public HourlyEmployee() {
}
public HourlyEmployee(String name, int month, double hourlySalary, int hours) {
super(name, month);
this.hourlySalary = hourlySalary;
this.hours = hours;
}
@Override
public double getSalary(int month) {
if(this.hours >= 160) {
return super.getSalary(month) + 160*hourlySalary + (hours-160)*hourlySalary*1.5;
}else{
return this.hourlySalary*this.hours+super.getSalary(month);
}
}
SalesEmployee类
SalesEmployee:Employee的子类,销售人员,工资由月销售额和提成率决定。
属性:月销售额(sales)、提成率(commission)
实现代码
public class SalesEmployee extends Employee{
private double sales;
private double commission;
public SalesEmployee() {
}
public SalesEmployee(String name, int month, double sales, double commission) {
super(name, month);
this.sales = sales;
this.commission = commission;
}
@Override
public double getSalary(int month) {
return super.getSalary(month)+this.sales*this.commission;
}
}
BasePlusSalesEmployee类
BasePlusSalesEmployee:SalesEmployee的子类,有固定底薪的销售人员,工资由底薪加上销售提成部分。
属性:底薪(baseSalary)。
实现代码
public class BasePlusSalesEmployee extends SalesEmployee{
private double baseSalary;
public BasePlusSalesEmployee() {
}
public BasePlusSalesEmployee(String name, int month, double sales, double commission, double baseSalary) {
super(name, month, sales, commission);
this.baseSalary = baseSalary;
}
@Override
public double getSalary(int month) {
return super.getSalary(month)+baseSalary;
}
十三、多态(语法)
多态就是一个面向对象语言中的使用方法。
13.1 多态最基础的使用方式
多态使用最基础的结构:
父类引用指向子类实例。
父类 引用 = new 子类();
13.2 多态的多在哪里
多态最表面的理解 ,就是多种形态。
因为父类引用与子类实例 之间 是一对多的关系。
所以同一个父类引用,可以指向多个不同的子类实例。
代码示例:
A a ;//这个a的引用,可以指向三种不同的实例。
a = new C();
a = new B();
a = new A();
13.3 多态调用方法的限制
当父类引用指向子类实例时,父类引用可以打点调用哪些方法?
1 只能调用在父类中声明过的方法。 因为引用是一个父类的类型。
2 可以调用父类中的方法。
3 子类重写的方法。
十四、多态的一般使用格式
使用父类引用做为方法的形参。
使用不同子类实例做为方法的实参。
class A {
public void dis(){
System.out.println("A.dis()!");
}
}
class B extends A{
@Override
public void dis() {
System.out.println("B.dis()!");
}
}
class C extends A{
@Override
public void dis() {
System.out.println("C.dis()!");
}
}
public class Test {
public static void dis(A a){
a.dis();
}
public static void main(String[] args) {
dis(new A());//A a = new A();
dis(new B());//A a = new B();
dis(new C());//A a = new C();
}
十五、多态练习:学校打印老师信息
学校老师(Teacher):每位老师都有打印信息的方式
老师有姓名(name)、年龄(age)、工资(salary)
老师还有外语老师、计算机老师、注册会计老师
外语老师(LanaguageTeacher)有外语语种(languages),外语等级(grade)
计算机老师(ComputerTeacher)有计算机语种(languages),项目职务(post)
注册会计老师(AccountantTeacher)有注册会计师证(id,保存证件编号就可以),注册会计师时间(date)
写一个学校类(School)。学校类负责打印每位教员的信息。
Teacher
public class Teacher {
private String name;
private int age;
private double salary;
public Teacher() {
}
public Teacher(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
}
School
public class School {
public void print(Teacher teacher){
System.out.println(teacher);
}
}
LanaguageTeache
public class LanaguageTeacher extends Teacher{
private String languages;
private int grade;
public LanaguageTeacher() {
}
public LanaguageTeacher(String name, int age, double salary, String languages, int grade) {
super(name, age, salary);
this.languages = languages;
this.grade = grade;
}
@Override
public String toString() {
return "LanaguageTeacher{" +
"languages='" + languages + '\'' +
", grade=" + grade +
"} " + super.toString();
}
}
ComputerTeacher
public class ComputerTeacher extends Teacher{
private String lanaguages;
private String post;
public ComputerTeacher() {
}
public ComputerTeacher(String name, int age, double salary, String lanaguages, String post) {
super(name, age, salary);
this.lanaguages = lanaguages;
this.post = post;
}
@Override
public String toString() {
return "ComputerTeacher{" +
"lanaguages='" + lanaguages + '\'' +
", post='" + post + '\'' +
"} " + super.toString();
}
}
main函数
public static void main(String[] args) {
LanaguageTeacher teacher1 = new LanaguageTeacher();
teacher1.setGrade(8);
teacher1.setLanguages("英语");
teacher1.setAge(25);
teacher1.setSalary(888888);
teacher1.setName("张老师");
ComputerTeacher teacher2 = new ComputerTeacher();
teacher2.setAge(25);
teacher2.setSalary(9999999);
teacher2.setName("孙老师");
teacher2.setLanaguages("Java");
teacher2.setPost("项目经理");
School school = new School();
school.print(teacher1);
school.print(teacher2);
}
十六、修饰符final关键字
final修饰符只能修饰到如下几个地方:
1 final 变量 =》表示这是一个常量值。不可以被修改
2 final 方法 =》表示这个方法不可以被重写。不可以被修改。
3 final 类 =》表示这个类不可以被继承。不可以被修改。
常量命名的规范:
1 全大写
2 每个单词之间用_分隔
例如:final int DAY_OF_YEAR = 365;
十七、修饰符static
static 中文名 静态
17.1 static可以修饰的4个地方
1 代码块 静态代码块
2 属性 静态属性
3 方法 静态方法
4 内部类 静态内部类(淘汰了)
17.2 静态代码块
static{
代码块;
}
静态代码块一定是写在类中的。
静态代码块是在类加载时被执行的。而且只会执行一次。
静态代码块的作用是为了给静态属性进行初始化操作。
示例代码:
public class A {
static {
System.out.println("静态代码块!");
}
public A() {
System.out.println("A类的构造方法!");
}
public static void main(String[] args) {
new A();
new A();
}
}
17.3 静态属性
为实例属性增加static修饰符之后。属性就变成了静态属性。
public class A {
private static int i ;//静态属性
private int j ;//实例属性
}
实例属性是属于每一个实例的。第一个实例都有自己的实例属性。实例属性是使用构造方法进行初始化。
静态属性是属于当前整个类的。这个类的每一个实例都共用同一个静态属性。
静态属性是在类加载时就创建了。使用静态代码码进行初始化操作。
静态方法的使用方法有两种:
1 对象名.静态属性
2 类名.静态属性
17.4 静态方法
作用范围:
静态方法属于当前整个类的。
使用 类名.静态方法() 调用。
使用静态方法来操作静态属性。
使用案例:
一般算法类的公式,都会写成静态方法。
Arrays.sort();给数组进行排序。
十八、单例模式
18.1 什么是单例模式
单例模式:表示一个类只能去创建一个实例。
class A{
}
A a1 = new A();
A a2 = new A();
18.2单例模式的第一步:私有化构造方法
第一步:私有构造方法。构造方法就只能在类内调用。
所以:实例只能在类内创建。
第二步:在类内创建实例。
第三步:让外部通过本类的静态方法来获取实例。
18.3 饿汉模式
public class SingletonA {
//第二步:本类中创建自己的静态实例。
private static SingletonA singletonA = new SingletonA();
//第一步:私有构造方法
private SingletonA() {
}
//第三步:静态方法,通过 类名.getSingletonA();
public static SingletonA getSingletonA() {
return singletonA;
}
}
18.4 懒汉模式
public class SingletonB {
private static SingletonB singletonB;
private SingletonB() {
}
public static SingletonB getSingletonB() {
if(singletonB == null) {
singletonB = new SingletonB();
}
return singletonB;
}
}
十九、封装、继承、多态
19.1 封装
封装就是将代码包装起来。 { }
在面向对象设计与分析中。封装最核心的目的是得到 类和方法。
方法:实现某一功能的代码的封装。
类:类是对大量对象的封装。封装相同的属性和方法。
父类:父类是对大量子类的封装。封装相同的属性和方法。
软件开发原则:将针对需求改变时,代码变化部分 与 代码不变的部分 分开 封装。
最经典的应用:dao层。数据库连接对象的工具类。
数据封装:使用private,public 访问修饰符。实现对数据的封装。
19.2 继承
public class B extends A{
}
B是子类。A是父类。
子类可以使用父类的属性和方法。(语法)
在面向对象的分析与设计中:
子类是对父类的修改。子类是对父类功能的扩展。
子类对父类进行修改和扩展时,需要依赖 方法重写。
在软件开发的原则:
is-a 子类是一个父类。
里氏替换原则 : 所有使用父类的地方,都可以使用其子类进行替换。
19.3 多态
多态只是一种语言特性。是一种特殊的使用方式。
多态:
父类引用 指向 子类实例。
A a = new B();
当前多态格式可以调用的方法有:
1 父类的方法
2 子类重写的方法
特别注意:子类自己的方法是不能被父类引用所调用的。
多态使用的一般格式:
1 父类引用做形参
public static void print(Person p){
System.out.println( p.toString() );
}
2 子类实例做实参
Stu s = new Stu();
Tea t = new Tea();
print(s);//传参是学员对象。print方法中调用学员类的toString()
print(t);//传参是教员对象。print方法中调用教员类的toString()
二十、修饰符abstract
20.1 abstract可以修饰2个位置
abstract可以修饰的位置:
1 方法 抽象方法
2 类 抽象类
20.2 抽象方法
抽象方法是一个没有方法体的方法。只有方法的原型。
实例方法:
public void print(int i){
sout(i);
}
抽象方法:
1 使用abstract修饰
2 没有方法体,只有原型。
publicabstract void print(int i);
我们认为抽象方法是一个没有写完的方法。就不可以执行。
抽象方法一定需要被重写。
20.3 抽象类
(1) 什么是抽象类
一个被abstract修饰符修饰的类就是一个抽象类。
public abstract class A{ }
有抽象方法的类,必须是一个抽象类。
(2) 抽象类的使用方法
我们认为抽象类是一个没有完成的类。就不可以被实例。
抽象类一定要被继承。
20.4 抽象类与抽象方法的使用方法
抽象类要继承
抽象方法要重写
A类(抽象类):
public abstract class A {
public void print(){
}
public static void dis(){
}
public abstract void info();
}
B类:
public class B extends A{
@Override
public void info() {
}
}
二十一、abstract 的使用场景
面向对象语言最合性的特性是:多态。
父类 引用 = new 子类();
这个引用可以调用的方法是:
1 父类的方法
2 子类重写方法
都是在父类中声明的。
条件1:多态时方法必须在父类中声明
条件2:父类没有方法的实现
因为很多父类本身就是一个抽象的概念
因为很多父类本身就是一个抽象的概念。
三角形,矩形,圆形都是具体的实例。
图形父类就是一个抽象的概念。
二十二、 访问修饰符
private,public都是访问修饰符。
在Java中一共有四个访问级别。但是只有三个访问修饰符关键字。
级别 | 关键字 | 本类 | 同包的其他类 | 不同包的子类 | 不同包的非子类 |
公有 | public | Y | Y | Y | Y |
保护 | protected | Y | Y | Y | |
默认 | (default) | Y | Y | ||
私有 | private | Y |
二十三、枚举(enum关键字)
enum也是类声明关键字。所以enum的级别与class是一致的。
23.1什么是枚举
枚举也是一种特殊的数据类型
枚举也是一种特殊的类
枚举就是一个有固定实例数量的类
例如计算机三原色RGB。交通信号灯颜色。季节。月份。
23.2枚举的定义格式
public enum RGB {
RED,GREEN,BLUE;
}
我们定义了一个枚举类型:RGB。
在这个类型中,有三个实例。分别是RED,GREEN,BLUE;
23.3 枚举使用的格式
枚举中第一个值,都是枚举的一个实例。
public class Test {
public static void main(String[] args) {
RGB rgb1 = RGB.RED;
RGB rgb2 = RGB.BLUE;
RGB rgb3 = RGB.GREEN;
}
}
23.4 枚举本质上就是一个Java类
枚举是在JDK5才加入的新特性。
在JDK5之前。我们都是使用Java类的方式实现枚举的要求。
这是在JDK5之前,一个类只有三个实例的标准写法。
public class RGBClass {
public final static RGBClass R = new RGBClass();
public final static RGBClass G = new RGBClass();
public final static RGBClass B = new RGBClass();
private RGBClass() {
}
}
在这个代码的基础上。我们把固定的代码删掉,会得到什么?
public class RGBClass {
R;
G;
B;
}
从用法上来看,枚举就是自带一些固定代码的特殊的类的用法
23.5 如何使用枚举类型
(1) 枚举一般配合switch一起使用
RGB rgb ;
switch (rgb1){
case RED:
System.out.println("red");
break;
case BLUE:
System.out.println("blue");
break;
case GREEN:
System.out.println("green");
break;
}
(2) 当一个方法的参数是一个枚举类型时
问:一个公司只有7个部门。用什么类型来表示这7个部门。
1 使用编号,int,分别1-7。
编写方法时。参数就是int。 public void print(int i){}
int数据类型合法的取值范围要比1-7大。
业务规范要求1-7的取值。但是语法要求合法的int类型太多了。
2 使用枚举。使用一个有7个实例的枚举。
编写方法时,参数是枚举类型。 public void print(RGB rgb){}
当RGB做为参数时,合法的取值有3个。RGB.RED , RGB.GREEN , RGB.BLUE;
23.6 枚举可以有属性和方法
枚举就是一个Java类。
public enum RGB {
RED,GREEN,BLUE;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
RGB.RED.setName(“红色”);
23.7 枚举中国可以有构造方法
在JDK5之前的方式如下:
public class RGBClass {
private String name;
public final static RGBClass R = new RGBClass("红");
public final static RGBClass G = new RGBClass("绿");
public final static RGBClass B = new RGBClass("蓝");
public RGBClass(String name) {
this.name = name;
}
}
删掉统一可以不写的内容后
public class RGBClass {
private String name;
R ("红");
G ("绿");
B ("蓝");
public RGBClass(String name) {
this.name = name;
}
}
按格式转换:枚举应该如下:
public enum RGB {
RED("红"),
GREEN("绿"),
BLUE("蓝");
private String name;
RGB(String name) {
this.name = name;
}
}
二十四、接口(interface)
24.1 接口的声明
接口interface关键字。与class,enum是同级。
public interface 接口名{
}
24.2 接口中的内容
JDK1.8之前
接口中只能写二种内容:
1 public static final int I; //公有静态常量。
2public abstractvoid dis(); //公有抽象方法。
JDK1.8之后
接口中又多了两种内容:
1 公有静态方法
2 公有实现方法(实例方法)(有方法体可以直接使用的方法)
static void print(){
System.out.println("公有静态方法!");
}
default void info(){
System.out.println("公有实例方法!");
}
24.3 接口的使用
接口中有抽象方法,所以接口本身不能被实例化。
接口的使用需要与类配合。与接口配合一起使用的类,我们叫实现类。
需要使用实现类。实现接口中的所有抽象方法。
实现的关键字:implements
public class 实现类 extends 父类 implements 接口列表{
方法重写(){ }
}
1实现类可以在继承一个父类的同时,实现接口。
2 使用implements 关键字实现接口。
3 Java只支持单继承,但是可以支持多实现。
public class Impl01 implements Inter01,Inter02{
}4 实现类应该实现接口中所有抽象方法。
public class Impl01 implements Inter01{
@Override
public void dis() {
System.out.println("实现类Impl01给出的方法实现!");
}
}
24.4 接口与实现类之间也支持多态
类的多态:
父类 引用 = new 子类( );
接口的多态:
接口 引用 = new 实现类( );
接口的引用打点可以调用实现类的重写方法。
public class Test {
public static void main(String[] args) {
Inter01 inter01 = new Impl01();
inter01.dis();
inter01.info();
}
}