课时1 面向对象简介

20180101

面向对象,模块化设计,具备可通用性,可重用

1. 封装性:内部的操作对外部不可见

2. 继承性:继续发展,可以重用设计

3. 多态性:利用这个特性得到良好的设计,可控范围内的状态改变

OOA面向对象分析

OOD面向对象设计

OOP面向对象编程

核心所在--考虑内存分配问题

面向过程,函数式过程,解决问题

20180102

课时2 类和对象(基本定义)

类:引用数据类型,内存分配问题

描述的群体共性特征(比如:人)

对象是一个具体的可以使用概念(比如具体的某个人)

类 ---> 对象

类的组成:方法(操作的行为),属性(变量,描述对象的基本特点)

课时3 类和对象(定义)

class ThisIsAClass {

属性1;

属性2;

方法1() {

方法内容

}

方法2() {

方法内容

}

}

属性可以无限定义,注意每一个方法中的代码不要太长,否则就要考虑重构;

声明并实例化对象

类名称 对象名称 = new 类名称();

分部进行

1. 声明:类名称 对象名称 = null;

2. 实例化: 对象名称 = new 类名称();

引用数据类型,new用于开辟新的堆内存;

性能调优:内存问题

对象只有实例化之后才能使用:

调用类中的属性 对象名称.属性;

调用类中的方法 对象名称.方法名();

课时4 类和对象(对象内存分析)

引用类型

堆内存:保存真正的数据,对象的属性信息

栈内存:保存的堆内存的地址,也就是堆内存的操作权

如果在定义类的时候没有给属性声明默认值,那么属性会采用类型的默认值,比如int是0,String是null

1个栈只能存储1个地址

声明并实例化对象方式:

分步方式:

如果只是声明对象,而不实例化,编译的时候不会报错,运行的时候会报错:NullPointerException

数组,类,接口会出现此类报错

课时5 类和对象(引用传递初次分析)

引用的本质是别名,别名存在栈内存中,1个堆内存可以被多个栈内存所指向(比如同一个人有多个外号,但是其实是指向同一个人)

内存分析(地址一样)

垃圾内存:(没有栈内存指向的堆内存空间,会被GC定期回收) GarbageCollection

课时6 private实现封装处理

面向对象编程有三大特性:封装、继承、多态

对象不能直接  .  操作类的属性

封装可以使用private实现(有其他实现方式,不唯一),只允许本类访问

方法一般不使用private

语法格式:

private 属性;

配置属性使用setter方法(可以对变量做合理判断),获取属性使用getter方法

publicclass Person {

private String name;

public void setName(String a) {

name = a;

}

public void getName() {

return name;

}

}

publicstatic void main (String[] args) {

Person per = new Person();

per.setName("test");

per.getName();'

}

规范:

类中的所有属性定义都是用private封装,如果需要被外部使用,就定义setter()和getter()方法

课时7 构造方法和匿名函数

实例化对象方式:

类名称 对象名称 =new 类名称();

类名称:任何对象都有其对应的类

对象名称:对象的唯一标记

new:开辟新的堆内存空间

类名称():构造方法

构造方法和类名称一样,无返回值,声明一个类之后就会自动生成一个无参数无返回值的默认构造函数(编译后)

new的时候才调用构造方法

类的组成,属性+普通方法+构造方法

publicclass Person {

private String name;

public Person() { //默认的构造方法格式

}

public void setName(String a) {

name = a;

}

public void getName() {

return name;

}

}

publicstatic void main (String[] args) {

Person per = new Person();

per.setName("test");

per.getName();'

}

构造方法不能带void修饰符,带有void的命令不标准,

publicvoid Person()

publicPerson()

对于内中可以自动生成默认构造方法,前提是类中没有定义同名的构造方法

构造方法可以把类中的属性初始化(传入参数的构造方法)

构造方法可以重载(不同参数类型,不同参数个数),注意定义结构,按照参数个数采用升序或者降序排列

定义类的步骤:

1. 写属性

2. 写构造方法

3. 写普通方法

匿名对象:

只有这样定义: newPerson();

没有栈空间,使用一次之后就成为垃圾内存

课时8 【第01个代码模型】综合案例:简单Java类

简单java类的开发要求

1. 类的名称有意义,可以明确的描述某一类事物

2. 类中所有的属性使用private封装,并提供setter()/getter()方法

3. 类中必须保留一个无参数的构造方法

4. 类中的所有方法不允许使用System.out方法,输出要在调用处完成

5. 类中应该提供一个返回类完整信息的方法,getInfo()

开发中最多是简单java类

开发原则

课时9 数组的定义和使用(基本概念)

一组相关类型的变量集合,可以按照统一的方式进行操作,是引用类型

数组动态初始化(声明之后,每个数据都为默认值,比如int为0)

1. 声明并开辟空间

数据类型[] 数组名称 =new 数据类型[长度]

或者

数据类型 数组名称[] =new 数据类型[长度]

2. 分部进行(先声明,再实例化)

数据类型[] 数组名称 =null

数组名称 =new 数据类型[长度]

操作方式:

数组的访问通过索引完成,索引从0开始,到数组长度-1

比如int[]data = new int[3],索引为0,1,2

- 数组初始化之后,每个数据都为默认值,比如int为0

- 是一个有序的集合操作,采用循环模式操作

- 数组长度data.length

课时10 数组的定义与使用(数组引用传递)

int[]data = new int[3];

int[]temp = null;

temp= data;

//temp和 data指向同一块堆内存

//data的栈内存存的是地址

课时11 数组的定义与使用(数组静态初始化)

数组定义的时候设定内容

语法:

1. 简化格式

数据类型数组名称[] ={value,value,...,value};

2. 建议使用,完整格式,可以使用匿名数组

数据类型 数组名称[]=new 数据类型[] {value,value,...,value};

intdata[] = new int[] {1,2,3,4,5,6};

缺陷:长度固定

课时12 数组的定义与使用(二维数组)

行列集合

数组[行索引][列索引]

语法模式和一维一样

intdata[][] = new int[][] { {1,2,3},{4,5},{6,7,8,9} };

遍历数组使用2重循环,外部行,内部列

for(int x=0; x < data.length; x++) {

for (int y=0; y < data[x].length; y++){

System.out.print(data[x][y]);

}

}

//开发过程中出现二维数组的概率不高

课时13 数组的定义与使用(数组与方法的操作)

方法接收数组(参数为数组)

publicstatic void printArray(int temp[]) {

//

}

方法返回数组

publicstatic int[] init() {

return new int[] {1,2,3,4,5};

}

传入数组,返回数组

publicstatic void inc(int arr[]) {

for (int x = 0; x < arr.length; x++) {

arr[x] *= 2;

}

}

课时14 数组的定义与使用(Java对数组的支持)

1. 数组排序(基本数据类型数组),升序

java.util.Arrays.sort(数组名称);

2. 数组拷贝(一个数组的部分内容替换另外一个数组的部分内容),连续替换

System.arraycopy(原数组名称,原数组起点,目标数组名称,目标数组起点);

//逻辑训练,开发用不上

课时15 数组的定义与使用(数组案例:数组数据统计)

数组的线性操作

最大,最小,平均,总和

循环操作模式完成

方法优化

课时16 数组的定义与使用(数组案例:数组排序)

1. 基础排序操作:

冒泡排序:

publicclass ArrayDemo {

public static void main(String[] args){

int score[] = {67, 69, 75, 87, 89, 90,99, 100};

for (int i = 0; i < score.length-1; i++){    //最多做n-1趟排序

for(int j = 0 ;j < score.length- i - 1; j++){    //对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)

if(score[j] < score[j +1]){    //把小的值交换到后面

int temp = score[j];

score[j] = score[j + 1];

score[j + 1] = temp;

}

}

System.out.print("第"+ (i + 1) + "次排序结果:");

for(int a = 0; a <score.length; a++){

System.out.print(score[a] +"\t");

}

System.out.println("");

}

System.out.print("最终排序结果:");

for(int a = 0; a <score.length; a++){

System.out.print(score[a] +"\t");

}

}

}

课时17 数组的定义与使用(数组转置)

首尾交换

1. 新定义一个空数组,然后把原数组的值从后到前存入新的数组

问题:开辟了两块相同的堆内存空间,造成浪费

2. 在原数组上反转

计算数组长度/2,交换次数为n,n =(array.length -1)/2

0 和length-1交换

1 和length-2交换

2 和length-3交换

n 和length-n-1交换

课时18 数组的定义与使用(二分查找法)

指定的数组中查找某个元素的位置

前提:数组先排序

mid =head/2 + tail/2

原理

比如一个排序好的数组

0,1,2,3,4,5,6,7,8

查找7

第一次查找

from:0

to:8

mid:4

索引为4的数比7小,所以赋值(第二次查找)

from:4+1

to:8

mid:(5+8)/2= 6

索引为6的数比7小,所以赋值(第三次查找)

from:6+1

to:8

mid:(7+8)/2= 7

索引为7的数为7,返回索引7

查找2

第一次查找

from:0

to:8

mid:4

索引为4的数比2大,所以赋值(第二次查找)

from:0

to:4-1

mid:(0+3)/2= 1

索引为1的数比2小,所以赋值(第三次查找)

from:1+1

to:3

mid:(2+3)/2= 2

索引为2的数为2,返回索引2

递归的结束条件是当from>= to

课时19 数组的定义与使用(对象数组)

核心掌握

引用数据类型为主,类或者接口

对象数组动态初始化: 类名称[] 对象数组名 =new 类名称[长度]

对象数组的静态初始化:类名称[] 对象数组名 =new 类名称[] {对象名,...}

classPerson {

private String name;

private int age;

public Person(String setName,int setAge){

name = setName;

age = setAge;

}

public String getInfo() {

return "name is " + name+ " age is " + age;

}

}

publicclass ArrayDemo {

public static void main(String[] args) {

Person[] per = new Person[3]; //动态初始化,默认值为null

per[0] = newPerson("A",1);

per[1] = newPerson("B",2);

per[2] = newPerson("C",3);

for (int x = 0; x < per.length;x++) {

System.out.println(per[x].getInfo());

}

Person[] per2 = new Person[] { newPerson("D",4) }; //静态初始化

System.out.println(per2[0].getInfo());

}

}

对象保存的是堆内存的地址

普通数据数组堆内存直接保存数据,比如newint[]

而对象数组堆内存表示各个对象的真是数据地址(里面没有数据),如上图

课时20 String类的基本特点(String类两种实例化方式)

所有开发过程中都存在String类

第一种

String str ="hello";

str是一个对象,hello是保存在堆内存中

第二种

Stringstr = new String("hello");

传入"hello"的名为String的构造函数

课时21 String类的基本特点(字符串比较)

== 和 equals的区别

==比较的是堆内存的地址,是数值比较

equals()比较的是字符串内容,区分大小小

String str1 ="hello"; //把一个匿名对象值为"hello"的对象命名为str1

String str2 = newString("hello");

str1 == str2 结果为false

str1.equals(str2) 结果为true

开发过程中必须使用equals()

课时22 String类的基本特点(字符串常量为匿名对象)

String str1 ="hello"; //把一个匿名对象值为"hello"的对象命名为str1

开发过程中,如果要判断用户输入的字符串是否等同于指定的字符串,一定要把字符串写在前面,考虑用户没有输入数据的问题

操作方法1:字符串写在前面,不会报空指向异常

课时23 String类的基本特点(String两种实例化区别)

第一种 直接赋值(开发推荐做法,节省内存)

String str ="hello";

str是一个对象,hello是保存在堆内存中

多次赋值(指向的是同一个堆内存),使用了共享设计模式

JVM维护对象池, 直接赋值的时候,第一次会保存到对象池,后续如果有一样的对象,就引用一样的对象

也就是一个对象数组,可以减少同样字符串的内存开销

第二种,构造方法(标准做法)

(从右往左执行)

Stringstr = new String("hello");

传入"hello"的名为String的构造函数

会开辟2个堆内存空间,其中一个成为垃圾空间

而且这个对象没有自动保存到对象池

实现入池的操作

publicString intern();

课时24 String类的基本特点(字符串常量不可变更)

字符串对象变更:

字符串内容本身是不会变化的,变化的是字符串对象的引用

开发原则:

字符串采用直接赋值模式完成

比较实用equals()方法实现

字符串不要频繁改变

课时25 String类的常用方法(DOC文档组成)

文档组成:

1. 类的相关定义,类的名字,父类,接口等

2. 类的简介

3. 成员(field)摘要,属性就是一种成员,

4. 构造(constructor)方法说明,Deprecated建议不用

5. 方法(methods)摘要,返回值,参数说明

课时26 String类的常用方法(字符串与字符数组)

字符数组 变成 字符串

public String(char[] value)//构造方法

public String(char[] value,int offset, int count) // offset开始,count个数,构造方法

public char charAt(int index)//返回字符串索引位置的字符,索引从0开始 开发中出现的几率很低,普通方法

字符串 变成 字符数组

publicchar[] toCharArray() //普通方法

重点:字符串和字符数组的互相转换

publicclass StringDemo {

public static void main(String[] args) {

String str = "helloworld";

System.out.println("index 2" + str.charAt(2));

char[] data = str.toCharArray();

for (char x : data) {

x -= 32; //转换成大写

System.out.print(x +"/");

}

System.out.println(newString(data));

System.out.println(newString(data,6,5));

}

}

课时27 String类的常用方法(字节与字符串)

字节:数据传输或者编码转换

支持:

构造方法:

public String(byte[] byte)

public String(byte[] byte,int offset, int length)

普通方法:

public byte[] getBytes()

public byte[] getBytes(StringcharsetName) throws UnsupportedEncodingException //编码转换

public class StringDemo {

public static void main(String[] args) {

String str = "hello world";

byte data[] = str.getBytes();

for (byte x : data) {

System.out.print(x + ",");

}

}

}

字节 -128 到 127 无法表示中文

字符才用于表示中文

课时28 String类的常用方法(字符串比较)

equals()方法

区分大小写

public boolean equals(StringanotherString)

不区分

public booleanequalsIgnoreCase(String anotherString)

public int compareTo(StringanotherString) //比较两个字符串的大小关系

相等返回0

如果不相等:

小于(每个字符进行对比,根据编码数字差返回第一个不相等的字符差)

大于(每个字符进行对比,根据编码数字差返回第一个不相等的字符差)

这个方法很重要

public class StringDemo {

public static void main(String[] args) {

String str1 = "hello";

System.out.println("Hello".equals(str1));

System.out.println("Hello".equalsIgnoreCase(str1));

System.out.println("A".compareTo("a"));

System.out.println("a".compareTo("A"));

System.out.println("abb".compareTo("adc"));

}

}

/*

E:\01_JAVA\project\java_basic\mldn\02\course_28>javaStringDemo

false

true

-32

32

-2

*/

课时29 String类的常用方法(字符串查找)- 重要

contains() // 普通方法,判断一个子字符串是否存在,返回booleanJDK1.5之后追加

indexOf() // 普通方法,查找子字符串的索引,返回第一个字符的位置索引,不存在则返回-1

indexOf(String str, intindex) //从指定位置开始查找

lastIndexOf() //从后向前找

lastIndexOf(String str, intindex) //从指定位置从后往前找

startsWith(String prefix) // 由指定子字符串开头

startsWith(String prefix, inttoffset) //从指定位置开始判断,由指定子字符串开头

endsWith(String prefix) //由指定子字符串结尾

建议使用contains()

课时30 String类的常用方法(字符串替换)

指定一个新的字符串替换字符串中的某个字符串

//需要替换的字符串 目标字符串

replaceAll(String regex,String replacement)

replaceFirst(String regex,String replacement)

课时31 String类的常用方法(字符串拆分)

string[] split(String regx)

string[] split(String regx,int limit) // 部分拆分,分成几段,2 代表2段 最大长度,如果没有到最大长度,那就有多少拆多少

\\转义字符

课时32 String类的常用方法(字符串截取)

substring(int beginindex) //从指定索引截取到结尾

substring)int beginindex, intendindex) //指定区间截取

索引从0开始

课时33 String类的常用方法(字符串其它操作方法)

trim() //去掉字符串的左右空格,一个或者多个

toUpperCase() //转大写

toLowerCase() //转小写

这两个函数,如果不是字母,那么就不做转换

intern() //字符串存入对象池

contact(String str) //字符串连接,跟+一样

length() //字符串长度

isEmpty() //判断是否为空字符串,长度为0,非null

没有提供首字符大写的方法

实现首字母大写的方法

课时34 this关键字(this调用属性)

this 可以调用

1. 本类属性

2. 本类方法(构造和普通)

3. 当前对象(相对概念)

下面赋值运行之后,name 为 null,age 为 0;

程序以大括号为边界,不会去找外部定义的属性name

参数与属性同名,解决方法

类的方法中有需要用到属性,一定在前面加this关键字

课时35 this关键字(this调用方法)

this.函数名称(参数)

this.构造方法名称(参数)

区分方法的定义来源(继承中有用)

java支持类构造方法的互相调用:

例子,使用2个参数的调用,先调用1个参数的,再赋值age,调用1个参数的时候,使用无参数的构造函数先输出一段信息,然后再赋值name

有以下几点要求

this()

1. this()必须放在构造方法的首行

2. 使用this()构造方法的时候留出口(递归死循环)(比如在上面这个例子中无参构造里面调用2个参数的构造函数)

课时36 this关键字(表示当前对象)

this指向p1

课时37 引用传递进阶分析

java核心

3个简单例子

第一个:

class Message {

private int num ;

public void setNum(int num) {

this.num = num ;

}

public int getNum() {

return this.num ;

}

}

public class TestDemo {

public static void main(String[] args) {

Message msg = new Message();

msg.setNum(100);

fun(msg);

System.out.println(msg.getNum());

}

public static void fun(Message temp) {

temp.setNum(30);

}

}

第二个:

public class TestDemo2 {

public static void main(String[] args) {

String str = "hello";

fun(str);

System.out.println(str);

}

public static void fun(String temp) {

temp = "world";

}

}

第三个:

classMessage2 {

private String note ;

public void setNote(String note) {

this.note = note ;

}

public String getNote() {

return this.note ;

}

}

publicclass TestDemo3 {

public static void main(String[] args) {

Message2 msg = new Message2();

msg.setNote("hello");

fun(msg);

System.out.println(msg.getNote());

}

public static void fun(Message2 temp) {

temp.setNote("world");

}

}

课时38 【第02个代码模型】综合案例:对象比较

比较两个对象的属性

实现形式1

classPerson {

private String name ;

private int age ;

public Person(String name, int age) {

this.name = name ;

this.age = age ;

}

public String getName() {

return this.name ;

}

public int getAge() {

return this.age ;

}

}

publicclass TestDemo1 {

public static void main(String[] args) {

Person perA = newPerson("A",20);

Person perB = newPerson("A",20);

System.out.println(perA == perB);

if(perA.getAge() == perB.getAge()&& perA.getName().equals(perB.getName())) {

System.out.println("perA == perB ");

}

}

}

// 这种形式在开发过程中不会出现,主方法需要出现的逻辑太多了

方法2

类方法自带比较方法

compare()

classPerson {

private String name ;

private int age ;

public Person(String name, int age) {

this.name = name ;

this.age = age ;

}

public String getName() {

return this.name ;

}

public int getAge() {

return this.age ;

}

//this表示当前对象,另外一个是传入对象

public boolean compare(Person per) {

if (per == this) {

return true;

}

if (per == null) {

return false;

}

if (this.name.equals(per.name)&& this.age == per.age) {

return true;

} else {

return false;

}

}

}

publicclass TestDemo2 {

public static void main(String[] args) {

Person perA = newPerson("A",20);

Person perB = new Person("A",20);

System.out.println(perA.compare(perB));

}

}

判断步骤:

1. 判断地址

2. 判断是否为空

3. 判断对象的各个属性

课时39 引用传递实际应用

引用传递是java核心

合成设计模式

class Member {

private String name;

private int age;

private Member child;

//car == null, 说明此人无车

private Car car;

public Member(String name, int age) {

this.name = name;

this.age = age;

}

public void setName(String name) {

this.name = name;

}

public String getName() {

return this.name;

}

public void setAge(int age) {

this.age = age;

}

public int getAge() {

return this.age;

}

public void setChild(Member child) {

this.child = child;

}

public Member getChild() {

return this.child;

}

public void setCar(Car car) {

this.car = car;

}

public Car getCar() {

return this.car;

}

public String getInfo() {

return "[Member] name = " + this.name + "age = " + this.age;

}

}

class Car {

private String car;

private double price;

private Member member;

public Car(String car, double price) {

this.car = car;

this.price = price;

}

public void setCar(String car) {

this.car = car;

}

public String getCar() {

return this.car;

}

public void setPirce(double price) {

this.price = price;

}

public double getPrice() {

return this.price;

}

public void setMem(Member member) {

this.member = member;

}

public Member getMember() {

return this.member;

}

public String getInfo() {

return "[car] car = " + this.car + "price = " + this.price;

}

}

public class TestDemo {

public static void main(String[] main) {

Member mem = new Member("A",30);

Car car = new Car("car-a",100);

Member child = new Member("B",2);

Car childCar = new Car("car-b",200);

mem.setCar(car);

mem.setChild(child);

car.setMem(mem);

child.setCar(childCar);

childCar.setMem(child);

System.out.println(mem.getInfo());

System.out.println(mem.getCar().getInfo());

System.out.println(car.getMember().getInfo());

System.out.println(mem.getChild().getInfo());

System.out.println(mem.getChild().getCar().getInfo());

}

}

课时40 【第03个代码模型】综合案例:数据表与简单Java类(一对多)

/**

1. 先定义基本类,包括属性,构造函数,getInfo()函数

2. 定义各个类之间的关系,雇员的领导,部门里面的所有雇员,雇员属于哪个部门

3. 实现开发需求

(1) 设置类对象间的关系

(2) 获取数据

*/

class Emp {

private int empno ;

private String ename ;

private String job ;

private double sal ;

private double comm ;

private Emp mgr ;

private Dept dept ;

public Emp() {}

public Emp(int empno, String ename, String job, double sal,double comm) {

this.empno = empno ;

this.ename = ename ;

this.job = job ;

this.sal = sal ;

this.comm = comm;

}

public void setMgr(Emp mgr) {

this.mgr = mgr ;

}

public Emp getMgr() {

return this.mgr ;

}

public void setDept(Dept dept) {

this.dept = dept ;

}

public Dept getDept() {

return this.dept ;

}

public String getInfo() {

return "[Emp] empno = " + empno

+ " ename = " + ename

+ " job = " + job

+ " sal = " + sal

+ " comm = " + comm;

}

}

class Dept {

private int deptno ;

private String dname ;

private String loc ;

private Emp[] emps;

public Dept() {}

public Dept(int deptno, String dname, String loc) {

this.deptno = deptno ;

this.dname = dname ;

this.loc = loc ;

}

public void setEmps(Emp[] emps) {

this.emps = emps ;

}

public Emp[] getEmps() {

return this.emps ;

}

public String getInfo() {

return "[Dept] deptno = " + deptno

+ " dname = " + dname

+ " loc = " + loc;

}

}

public class TestDemo {

public static void main(String[] args) {

Dept dept = new Dept(10,"accounting","newyork");

Emp ea = newEmp(1,"A","Job-a",100.0,1.0);

Emp eb = newEmp(1,"B","Job-b",200.0,2.0);

Emp ec = newEmp(1,"C","Job-c",300.0,3.0);

ea.setMgr(eb);

eb.setMgr(ec);

ea.setDept(dept);

eb.setDept(dept);

ec.setDept(dept);

dept.setEmps(new Emp[] {ea,eb,ec});

System.out.println(dept.getInfo());

for (Emp emp : dept.getEmps()) {

System.out.println("\t |-" +emp.getInfo());

if (emp.getMgr() != null) {

System.out.println("\t\t |-" +emp.getMgr());

}

}

System.out.println(eb.getInfo());

if (eb.getMgr() != null) {

System.out.println("\t |-" +eb.getMgr().getInfo());

}

if (eb.getDept() != null) {

System.out.println("\t\t |-" +eb.getDept().getInfo());

}

}

}

课时41 【第03个代码模型】综合案例:数据表与简单Java类(多对多)

/**

基本信息:

学生表:编号,姓名,年龄,

课程表:编号,名称,学分

学生-课程关系表:学生编号,课程编号,成绩

需求:

1. 找到一门课程,参加此课程的所有学生信息和成绩

2. 找到一个学生,参加的课程的课程信息和成绩

设计过程:

1. 定义基本类,前2个表,

2. 第三个表是学生选课信息

3. 筛选关系,去掉第一步做的学生中的课程对象数组,取出课程中的学生数组,因为第二部中设计的表可以

表达关系了

4. 输出关系

*/

class Student {

private int studentId;

private String studentName;

private int studentAge;

private StudentCourse[] studentCourse;

public Student() {}

public Student(int studentId, String studentName, intstudentAge) {

this.studentId = studentId;

this.studentName = studentName;

this.studentAge = studentAge;

}

public void setStudentCourse(StudentCourse[] studentCourse) {

this.studentCourse = studentCourse;

}

public StudentCourse[] getStudentCourse() {

return this.studentCourse;

}

public String getInfo() {

return "[Student] ID = " + this.studentId

+ " Name = " + this.studentName

+ " Age = " + this.studentAge;

}

}

class Course {

private int courseId;

private String courseName;

private int credit;

private StudentCourse[] studentCourse;

public Course() {}

public Course(int courseId, String courseName, int credit) {

this.courseId = courseId;

this.courseName = courseName;

this.credit = credit;

}

public void setStudentCourse(StudentCourse[] studentCourse) {

this.studentCourse = studentCourse;

}

public StudentCourse[] getStudentCourse() {

return this.studentCourse;

}

public String getInfo() {

return "[Course] ID = " + this.courseId

+ " Name = " + this.courseName

+ " credit = " + this.credit;

}

}

class StudentCourse {

private Student student;

private Course course;

private double score;

public StudentCourse() {}

public StudentCourse(Student student, Course course, doublescore) {

this.student = student;

this.course = course;

this.score = score;

}

public Student getStudent() {

return this.student;

}

public Course getCourse() {

return this.course;

}

public double getScore() {

return this.score;

}

public String getInfo() {

return //this.student.getInfo()

//+ this.course.getInfo()

//+

"[score] score = " + this.score;

}

}

public class TestDemo {

public static void main(String[] args) {

Student a = new Student(1,"a",18);

Student b = new Student(2,"b",19);

Student c = new Student(3,"c",20);

Course ca = new Course(1,"ca",10);

Course cb = new Course(2,"cb",20);

Course cc = new Course(3,"cc",30);

a.setStudentCourse(new StudentCourse[] {

new StudentCourse(a,ca,100.0),

new StudentCourse(a,cb,100.0),

new StudentCourse(a,cc,100.0)

});

b.setStudentCourse(new StudentCourse[] {

new StudentCourse(b,ca,90.0),

new StudentCourse(b,cb,90.0),

new StudentCourse(b,cc,90.0)

});

c.setStudentCourse(new StudentCourse[] {

new StudentCourse(c,ca,80.0),

new StudentCourse(c,cb,80.0),

//new StudentCourse(b,cc,90)

});

ca.setStudentCourse( new StudentCourse[] {

new StudentCourse(a,ca,100.0),

new StudentCourse(b,ca,90.0),

new StudentCourse(c,ca,80.0)

});

cb.setStudentCourse( new StudentCourse[] {

new StudentCourse(a,cb,100.0),

new StudentCourse(b,cb,90.0),

new StudentCourse(c,cb,80.0)

});

cc.setStudentCourse( new StudentCourse[] {

new StudentCourse(a,cb,100.0),

new StudentCourse(b,cb,90.0)

});

System.out.println("******************************");

System.out.println(a.getInfo());

System.out.println(b.getInfo());

System.out.println(c.getInfo());

System.out.println("******************************");

System.out.println(ca.getInfo());

System.out.println(cb.getInfo());

System.out.println(cc.getInfo());

System.out.println("******************************");

System.out.println(ca.getInfo());

for (int x = 0; x < ca.getStudentCourse().length;x++) {

System.out.println("\t |- " +ca.getStudentCourse()[x].getStudent().getInfo() + "\n\t\t |- " +ca.getStudentCourse()[x].getInfo());

}

System.out.println("******************************");

System.out.println(a.getInfo());

for (int x = 0; x < a.getStudentCourse().length; x++){

System.out.println("\t |- " +a.getStudentCourse()[x].getCourse().getInfo() + "\n\t\t |- " +ca.getStudentCourse()[x].getInfo());

}

}

}

课时42 【第03个代码模型】综合案例:数据表与简单Java类(角色与权限)

1. 进行单独类的描述

Dept //部门

Emp //员工

Role //角色

Privilege //权限

属性

构造函数

getInfo()函数

2. 进行关系的描述

一个部门有多个员工 ,且只有一个角色

员工只有一个部门

角色有多个部门,多个权限

权限有多个角色

角色-权限是2个外键(没有其他多的数据,上个例子有个成绩),不需要建表

3. 实现数据输出

创建部门数据,2个

创建员工数据,5个

创建角色信息,2个

创建权限数据,4个

部门和雇员

雇员和部门

部门和角色

角色和部门

设置角色和权限的关系

设置权限和角色的关系

4. 取出数据

完毕

class Dept {

private int deptID;

private String deptName;

private Emp[] emps;

private Role role;

public Dept() {}

public Dept(int deptID, String deptName) {

this.deptID = deptID;

this.deptName = deptName;

}

public void setEmps(Emp[] emps) {

this.emps = emps;

}

public Emp[] getEmps() {

return this.emps;

}

public void setRole(Role role) {

this.role = role;

}

public Role getRole() {

return this.role;

}

public String getInfo() {

return "[Dept] deptID = " + this.deptID

+ " deptName = " + this.deptName;

}

}

class Emp {

private int empId;

private String empName;

private Dept dept;

public Emp() {}

public Emp(int empId, String empName) {

this.empId = empId;

this.empName = empName;

}

public void setDept(Dept dept) {

this.dept = dept;

}

public Dept getDept(){

return this.dept;

}

public String getInfo() {

return "[Emp] empId = " + this.empId

+ " empName = " + this.empName;

}

}

class Role {

private int roleId;

private String roleName;

private Dept[] depts;

private Privilege[] privileges;

public Role() {}

public Role(int roleId, String roleName) {

this.roleId = roleId;

this.roleName = roleName;

}

public void setDepts(Dept[] depts) {

this.depts = depts;

}

public Dept[] getDepts() {

return this.depts;

}

public void setPrivileges(Privilege[] privileges) {

this.privileges = privileges;

}

public Privilege[] getPrivileges() {

return this.privileges;

}

public String getInfo() {

return "[Role] roleId = " + this.roleId

+ " roleName = " + roleName;

}

}

class Privilege {

private int pId;

private String pName;

private String pFlag;

private Role[] roles;

public Privilege() {}

public Privilege(int pId, String pName, String pFlag) {

this.pId = pId;

this.pName = pName;

this.pFlag = pFlag;

}

public void setRoles(Role[] roles) {

this.roles = roles;

}

public Role[] getRoles() {

return this.roles;

}

public String getInfo() {

return "[Privilege] pId = " + pId

+ " pName = " + pName

+ " pFlag = " + pFlag;

}

}

public class TestDemo {

public static void main(String[] args) {

Dept deptA = new Dept(1,"财务部");

Dept deptB = new Dept(2,"技术部");

Dept deptC = new Dept(3,"行政部");

Emp empA = new Emp(1,"员工A");

Emp empB = new Emp(2,"员工B");

Emp empC = new Emp(3,"员工C");

Emp empD = new Emp(4,"员工D");

Emp empE = new Emp(5,"员工E");

Role roleA = new Role(1,"普通员工");

Role roleB = new Role(2,"高级员工");

Privilege PA = new Privilege(1000,"查询","正常");

Privilege PB = new Privilege(1001,"删除","正常");

Privilege PC = new Privilege(1002,"修改","正常");

empA.setDept(deptA);

empB.setDept(deptA);

empC.setDept(deptB);

empD.setDept(deptB);

empE.setDept(deptC);

deptA.setEmps(new Emp[] {empA,empB});

deptB.setEmps(new Emp[] {empC,empD});

deptC.setEmps(new Emp[] {empE});

deptA.setRole(roleA);

deptB.setRole(roleA);

deptC.setRole(roleB);

roleA.setDepts(new Dept[] {deptA,deptB});

roleB.setDepts(new Dept[] {deptC});

roleA.setPrivileges(new Privilege[] {PA});

roleB.setPrivileges(new Privilege[] {PA,PB,PC});

PA.setRoles(new Role[] {roleA,roleB});

PB.setRoles(new Role[] {roleB});

PC.setRoles(new Role[] {roleB});

System.out.println(empA.getInfo());

System.out.println("\t |-" +empA.getDept().getInfo());

System.out.println("\t\t |-" +empA.getDept().getRole().getInfo());

for (Privilege x :empA.getDept().getRole().getPrivileges()) {

System.out.println("\t\t\t |-" +x.getInfo());

}

System.out.println(roleA.getInfo());

for (Dept x : roleA.getDepts()) {

System.out.println("\t |- " +x.getInfo());

for (Emp y : x.getEmps()) {

System.out.println("\t\t|- " + y.getInfo());

}

}

System.out.println(PA.getInfo());

for (Role x : PA.getRoles()) {

System.out.println("\t |- " +x.getInfo());

for (Dept y : x.getDepts()) {

System.out.println("\t\t |- " +y.getInfo());

for(Emp z : y.getEmps()) {

System.out.println("\t\t\t |- "+ z.getInfo());

}

}

}

}

}

课时43 static关键字(static属性)

class Person {

private String name;

private int age;

String country = "China";

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public String getInfo() {

return "[Person] name = " + this.name

+ " age = " + this.age

+ " country = " + this.country;

}

}

public class TestDemo {

public static void main(String[] args) {

Person p1 = new Person("张三",10);

Person p2 = new Person("李四",11);

Person p3 = new Person("王五",12);

System.out.println(p1.getInfo() + "\n" +p2.getInfo() + "\n" + p3.getInfo());

}

}

以上country对象被重复保存了

需要把country变为共享属性

加static关键字

class Person {

private String name;

private int age;

static String country = "China";

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public String getInfo() {

return "[Person] name = " + this.name

+ " age = " + this.age

+ " country = " + this.country;

}

}

public class TestDemo {

public static void main(String[] args) {

Person p1 = new Person("张三",10);

Person p2 = new Person("李四",11);

Person p3 = new Person("王五",12);

p1.country = "USA";

System.out.println(p1.getInfo() + "\n" +p2.getInfo() + "\n" + p3.getInfo());

}

}

/*

E:\01_JAVA\project\java_basic\mldn\02\course_43>javacTestDemo.java

E:\01_JAVA\project\java_basic\mldn\02\course_43>javaTestDemo

[Person] name = 张三 age = 10 country = USA

[Person] name = 李四 age = 11 country = USA

[Person] name = 王五 age = 12 country = USA

E:\01_JAVA\project\java_basic\mldn\02\course_43>

*/

这样就不保存在堆内存中,而是保存在全局数据区的内存空间中,所有对象都可以对该数据区进行访问

此时代码可以通过一个对象修改,static要通过类名称直接调用,不要使用对象

语法

Person.country ="AA";

static属性不受实例化影响,创建对象前就可以操作

选择:是否选用static关键字

定义类99%的情况下不采用static属性

如果需要描述共享属性的概念,或者不希望收到实例化对象控制的时候,使用static

课时44 static关键字(static方法)

限制,语法规定:

所有的static方法不允许调用非static定义的属性和方法

所有的非static方法允许调用static定义的属性和方法

原因:所有的static方法可以再没有实例化对象的时候访问。

使用static方法的目的:某些方法不希望受到类实例化对象的限制。

课时45 static关键字(分析主方法)

public static voidmain(String[] args)

主方法中定义方法的语法

public static 返回值 方法名(参数)

比如 public static void Print() {

//

}

如果没加static,那么就是类中的方法,需要实例化使用

public static voidmain(String[] args)

public 表示公共,主方法作为程序起点,必须可以被公共使用

static 执行java程序的时候是类名称,不受实例化限制

void 主方法是起点,没有返回值

main 系统定义的方法名称

String[] args 参数,都是String

课时46 static关键字(static应用)

1. static对象的计数统计

class Person {

private static int count = 0;

public Person() {

System.out.println( ++count );

}

}

public class TestDemo {

public static void main(String[] args) {

Person p1 = new Person();

Person p2 = new Person();

Person p3 = new Person();

}

}

2. static实现 调用无参构造对属性做自动赋值,给属性自动命名

class Person {

private String name;

private static int count = 0;

public Person() {

this("NONAME - " + ++count); //调用本类有参构造

}

public Person(String name) {

this.name = name;

}

public String getName() {

return this.name;

}

}

public class TestDemo {

public static void main(String[] args) {

System.out.println(new Person().getName());

System.out.println(new Person("MLDN"));

System.out.println(new Person().getName());

}

}

总结:

static属性和方法不是定义类的首要选择

static属性和方法不受类的实例化对象限制,可以直接通过类名称调用

课时47 代码块(普通代码块)

不重要的概念,清楚结构即可

使用{}定义的一段代码

1. 普通代码块

2. 构造代码块

3. 静态代码块

4. 同步代码块(多线程)

普通代码块:

定义在方法中的代码块

public class TestDemo {

public static void main(String[] args) {

{//代码块

int x = 10;

System.out.println( "x = " + x);

}//代码块

int x = 100;

System.out.println( "x = " + x);

}

}

作用:避免变量重名

作用不大

课时48 代码块(构造块)

类中的代码块

class Person {

{//构造块1

System.out.println("1");

}

{//构造块2

System.out.println("2");

}

public Person() {

System.out.println("4");

}

{//构造块3

System.out.println("3");

}

}

public class TestDemo {

public static void main(String[] args) {

new Person();

new Person();

}

}

E:\01_JAVA\project\java_basic\mldn\02\course_48>javaTestDemo

1

2

3

4

1

2

3

4

E:\01_JAVA\project\java_basic\mldn\02\course_48>

先会执行构造块,再执行构造方法

普通手段,没有什么意义,掌握概念即可

课时49 代码块(静态代码块)

使用static关键字定义的代码块

1. 非主类定义的

2. 主类中定义的

class Person {

{//构造块1

System.out.println("1");

}

{//构造块2

System.out.println("2");

}

public Person() {

System.out.println("4");

}

{//构造块3

System.out.println("3");

}

static {//静态块

System.out.println("5");

}

}

public class TestDemo {

public static void main(String[] args) {

new Person();

new Person();

}

}

静态块优先于构造块执行

E:\01_JAVA\project\java_basic\mldn\02\course_49>javacTestDemo.java

E:\01_JAVA\project\java_basic\mldn\02\course_49>javaTestDemo

5

1

2

3

4

1

2

3

4

E:\01_JAVA\project\java_basic\mldn\02\course_49>

用于static属性初始化

classPerson {

private static String info ="hello";

{//构造块1

System.out.println("1");

}

{//构造块2

System.out.println("2");

}

public Person() {

System.out.println("4");

}

{//构造块3

System.out.println("3");

}

static {//静态块

info += " world";

System.out.println(info);

}

}

publicclass TestDemo {

public static void main(String[] args) {

new Person();

new Person();

}

}

E:\01_JAVA\project\java_basic\mldn\02\course_49>javacTestDemo.java

E:\01_JAVA\project\java_basic\mldn\02\course_49>javaTestDemo

helloworld

1

2

3

4

1

2

3

4

E:\01_JAVA\project\java_basic\mldn\02\course_49>

在主类中使用:

publicclass TestDemo {

static {

System.out.println("*********************");

}

public static void main(String[] args) {

System.out.println("helloworld");

}

}

E:\01_JAVA\project\java_basic\mldn\02\course_49>javacTestDemo.java

E:\01_JAVA\project\java_basic\mldn\02\course_49>javaTestDemo

*********************

helloworld

E:\01_JAVA\project\java_basic\mldn\02\course_49>

课时50 内部类的定义及使用(内部类基本概念)

暂时不作为首要的类设计原则

概念,一个类之内进行其他类结构嵌套的语法形式

class Outer {

private String msg = "out";

class Inner {

public void print() {

System.out.println(msg);

}

}

public void fun() {

Inner in = new Inner();

in.print();

}

}

public class TestDemo {

public static void main(String[] args) {

Outer out = new Outer();

out.fun();

}

}

--- 程序结构混乱

好处:外部类对内部类的私有属性访问,内部类对外部类的私有属性访问

例子:

两个独立类,访问外部类的私有属性,会很复杂

class Outer {

private String msg = "out";

public String getMsg() {

return this.msg;

}

public void fun() {

Inner in = new Inner(this);

in.print();

}

}

class Inner {

private Outer out;

public Inner(Outer out) {

this.out = out;

}

public void print() {

System.out.println(out.msg);

}

}

public class OuterDemo {

public static void main(String[] args) {

Outer out = new Outer();

out.fun();

}

}

内部类的操作:

1. 内部类的访问需要通过外部类的方法完成,如果不想这么执行,那么需要进行实例化对象

外部类.内部类 内部类对象 = new 外部类().new 内部类();

进行外部类的实例化是因为外部类中有普通属性,需要开辟空间,所以先new外部类

2. 不直接产生内部类对象

private class Inner() {

//

}

外部类需要创建方法

Inner in = new Inner()

new Outer().fun()

3. 外部类当前对象的属性Outter.this.属性

课时51 内部类的定义及使用(static定义内部类)

static定义,表示外部类的形式(结构和功能一样),这个内部类只能访问外部类中的static属性和操作

如果要操作外部类:

语法:

实例化对象: 外部类.内部类 内部类对象名称 = new 外部类.内部类();

了解即可

课时52 内部类的定义及使用(在方法中定义内部类)

在方法中定义内部类的形式是最多的

问题:JDK1.8正常,之前的版本都是错误的

JDK1.7之前,如果方法中的内部类需要访问参数,参数必须使用final定义

编程中根据jdk版本决定是否加final

内部类使用暂时不作为首选

课时53 继承的定义与使用(继承问题的引出)

面向对象的第二个特点

在已有的基础上进行功能的扩充

消除结构定义上的重复

课时54 继承的定义与使用(继承的实现)

extends

语法

class 子类 extends 父类 {

}

子类可以直接继承父类的操作,属性和方法

扩充

课时55 继承的定义与使用(继承使用限制)

1. 子类对象在实例化前,先会实例化父类,调用父类的构造方法,再实例化子类,调用子类的构造方法

其实子类的构造方法隐含了super()方法

需要注意的是父类没有无参构造,那么super必须指定父类的构造方法

2. 只允许单继承,不允许多继承

一个子类只能继承一个父类

但是可以使用多层继承,一般建议3层最多

3. 进行继承的时候,子类会继承父类的所有结构。

私有属性,构造方法,普通方法

显示继承(直接调用)

操作父类的私有属性,隐式继承(setter和getter)

所有的private操作肯定无法直接使用

需要掌握:

1、继承的语法和目的

2、子类对象的实例化流程

3、继承的限制

扩展已有类的功能 ===== 代码重用

课时56 覆写(方法覆写)

重点核心

子类定义了与父类方法名称、参数类型和个数完全相同的方法,不能有比父类更严格的访问权限

 

 

进行复写使用的时候,需要关注

1、当前使用的对象是使用哪个类new的

2、调用方法如果被子类重写过,则会调用子类的方法

注意:

被复写的方法不能比父类有更严格的访问权限

private < default <public

父类中使用default权限,那么子类可以使用default/public

方法使用public

属性使用private

但是:

如果父类中使用private,子类中不能使用public,这样子类的中属于新方法,不属于复写

重载 复写

overloading override

重载:方法名称相同,参数类型和个数不同(返回值可以不同,但是开发规范建议不要)

在同个类中

无权限要求

复写:

方法名称,参数类型和个数,返回值都一样

在继承关系中提现

子类同个方法不能拥有比父类更严格的权限控制

课时57 覆写(属性覆盖)

子类定义了和父类 名称相同的属性

按照就近取用,取子类的属性

这个操作本身没有意义,因为属性都采用Private封装,且开发过程中不要使用重名属性

课时58 覆写(super关键字)

super.方法()

super.属性

子类调用父类

开发原则:在子类中使用父类方法和属性的时候,使用super

super和this的区别

this:

访问本类中的属性和方法

先查找本类,如果本类没有则查找本类

表示当前对象

super:

访问父类中的属性和方法

不查找本类,直接找父类

1、子类复写弗雷德方法是因为父类的方法功能不足,才需要复写

2、方法复写的时候使用的是public权限

课时59 综合案例:数组操作(定义Array父类)

class Array {

private int[] data;

private int foot;

public Array(int length) {

if (length > 0)

this.data = new int [length];

else

this.data = new int [1];

}

public boolean add(int num) {

if (this.foot >= this.data.length) {

return false;

} else {

this.data[foot++] = num;

return true;

}

}

public class TestDemo {

public static void main(String[] args) {

Array array = new Array(5);

}

}

class Array {

private int[] data;

private int foot;

public Array(int length) {

if (length > 0)

this.data = new int [length];

else

this.data = new int [1];

}

public boolean add(int num) {

if (this.foot >= this.data.length) {

return false;

} else {

this.data[foot++] = num;

return true;

}

}

public int[] getData() {

return this.data;

}

public void inc(int num) {

int[] newData = new int[this.data.length + num];

System.arraycopy(this.data,0,newData,0,this.data.length);

this.data = newData;

}

}

public class TestDemo {

public static void main(String[] args) {

Array array = new Array(5);

System.out.println(array.add(10));

System.out.println(array.add(9));

System.out.println(array.add(8));

System.out.println(array.add(7));

System.out.println(array.add(6));

array.inc(4);

System.out.println(array.add(5));

System.out.println(array.add(4));

System.out.println(array.add(3));

System.out.println(array.add(2));

System.out.println(array.add(1));

for (int x : array.getData()) {

System.out.print(x + ", ");

}

System.out.println();

}

}

课时60 综合案例:数组操作(SortArray排序子类)

class Array {

private int[] data;

private int foot;

public Array(int length) {

if (length > 0)

this.data = new int [length];

else

this.data = new int [1];

}

public boolean add(int num) {

if (this.foot >= this.data.length) {

return false;

} else {

this.data[foot++] = num;

return true;

}

}

public int[] getData() {

return this.data;

}

public void inc(int num) {

int[] newData = new int[this.data.length + num];

System.arraycopy(this.data,0,newData,0,this.data.length);

this.data = newData;

}

}

class SortArray extends Array{

//父类中没有无参数的构造方法,因此子类必须明确调用父类中的有参构造方法

public SortArray(int num) {

super(num);

}

public int[] getData() {

java.util.Arrays.sort(super.getData());

return super.getData(); //引用传递

}

}

public class TestDemo {

public static void main(String[] args) {

SortArray array = new SortArray(5);

System.out.println(array.add(10));

System.out.println(array.add(9));

System.out.println(array.add(8));

System.out.println(array.add(7));

System.out.println(array.add(6));

array.inc(4);

System.out.println(array.add(5));

System.out.println(array.add(4));

System.out.println(array.add(3));

System.out.println(array.add(2));

System.out.println(array.add(1));

for (int x : array.getData()) {

System.out.print(x + ", ");

}

System.out.println();

}

}

不同的子类要根据不同的需求进行扩写

课时61 综合案例:数组操作(ReverseArray反转子类)

class Array {

private int[] data;

private int foot;

public Array(int length) {

if (length > 0)

this.data = new int [length];

else

this.data = new int [1];

}

public boolean add(int num) {

if (this.foot >= this.data.length) {

return false;

} else {

this.data[foot++] = num;

return true;

}

}

public int[] getData() {

return this.data;

}

public void inc(int num) {

int[] newData = new int[this.data.length + num];

System.arraycopy(this.data,0,newData,0,this.data.length);

this.data = newData;

}

}

class SortArray extends Array{

//父类中没有无参数的构造方法,因此子类必须明确调用父类中的有参构造方法

public SortArray(int num) {

super(num);

}

public int[] getData() {

java.util.Arrays.sort(super.getData());

return super.getData(); //引用传递

}

}

class ReverseArray extendsArray {

public ReverseArray(int num) {

super(num);

}

public int[] getData() {

int mid = super.getData().length/2;

int head = 0;

int tail = super.getData().length-1;

for (int x = 0; x < mid; x++) {

int temp = super.getData()[head];

super.getData()[head] = super.getData()[tail];

super.getData()[tail] = temp;

head++;

tail--;

}

return super.getData();

}

}

public class TestDemo {

public static void main(String[] args) {

ReverseArray array = new ReverseArray(5);

System.out.println(array.add(10));

System.out.println(array.add(9));

System.out.println(array.add(8));

System.out.println(array.add(7));

System.out.println(array.add(6));

array.inc(4);

System.out.println(array.add(5));

System.out.println(array.add(4));

System.out.println(array.add(3));

System.out.println(array.add(2));

System.out.println(array.add(1));

for (int x : array.getData()) {

System.out.print(x + ", ");

}

System.out.println();

}

}

课时62 final关键字

可以定义 类

方法

属性

1、定义类的时候不能有子类,不能继承

2、final定义的方法不能被子类复写

3、final定义的变量为常量,不能修改

全局常量的定义:标识符全大写

public static final intFINAL_INT = 0;

课时63 多态性

重要!

核心表现:

1、方法多态

方法的重载

方法的复写

2、对象的多态性

实现前提:方法覆写

[自动]对象的向上转型:父类 父类对象 = 子类实例; 例如int到double

[强制]对象的向下转型:子类 子类对象 = (子类)父类实例; 例如 double到int double = (int)数据

不转型,例如String

向上转型的情况,父类不可以调用子类中的方法

只有强制转换到 向下转型 才可以调用子类的方法

【实际开发过程中用不到】不是所有的父类对象都可以向下转型,如果要实现向下转型,必须先向上转型,

否则会出现ClassCastException异常(两个不同的类发生转换)

判断后再转型:

instanceof

语法:

子类对象 instanceof 类名称

返回boolean

对象多态性:子类和父类之间的转换

向上转型核心用途:接收参数的操作统一

 

 

向下转型:子类扩充方法的调用

以后的开发过程中不要出现向下转型

课时64 抽象类的定义与使用(抽象类基本概念)

实际项目开发过程中,子类继承的必须是抽象类

抽象类:基本类扩充了抽象方法(只声明,没有方法体)

抽象类会要求子类必须重写抽象方法,比普通类要规范,普通类继承的时候可以不重写方法

abstract关键字

使用:

抽象类无法直接实例化

1、所有的抽象类必须要有子类

2、抽象类的子类(不是抽象类)必须复写抽象类的全部抽象方法

---方法复写要考虑权限问题,最好一直使用public方法,而且private和abstract不能同时修饰同一个方法

3、抽象类的对象可以通过多态性,利用子类实例化

另外一种实现方式:(A类的子类只有1个B),这种设计形式比较少,内部提供子类。

对封装性有好处,不作为开发首选。

课时65 抽象类的定义与使用(抽象类使用限制)

抽象类有构造方法,子类实例化的时候会先实例化父类

如果父类没有无参构造,那么子类要用super()指定父类的有参构造

另外一个问题:

程序输出为0

实例化操作:

1、类加载

2、对象实例化,空间开辟

3、调用构造方法,属性初始化

结论:如果构造方法没有执行,那么对象的属性都是其默认值

抽象类中允许不定义抽象方法,但是依然无法直接从抽象类实例化

抽象类不能使用final声明,抽象方法不能使用private定义

抽象类分为内部抽象类(可以使用static定义),描述为外部抽象类

课时66 抽象类的定义与使用(模版设计模式)

抽象类强制规定了子类的实现结构,更多情况下起到模板的作用

最具代表性的是:Servlet

1、抽象类单继承局限

2、抽象类的使用要通过子类实例化使用

课时67 接口的定义与使用(接口基本概念)

抽象类,避免单继承缺点就要使用接口

开发设计原则:使用接口优先

基本概念:一个抽象方法+全局常量的集合

语法:使用interface

接口命名前加大写的I

子类使用接口,可以实现多个接口,接口可以实现多继承的概念,关键字implements

如果子类不是抽象类,就需要重写接口中的所有抽象方法

接口之间的转化

一个子类继承了多个接口,通过子类实例化之后,接口之间可以互相转换

课时68 接口的定义与使用(接口使用限制)

1、接口里只能有public权限

以后编写接口的时候,接口的方法上需要加上public

2、一个子类要继承父类和多个接口的时候,要使用extends先,再跟上implements

3、一个抽象类可以使用多个implements继承多个接口,接口不能继承抽象类

三层继承,以后经常会见到的操作形式

4、一个接口可以使用extends继承多个父接口

5、接口可以定义一系列的内部接口,包括:内部普通类,内部抽象类,内部接口,其中使用static定义的接口

可以视为外部接口

课时69 接口的定义与使用(使用接口定义标准

接口可以表示一个标准

三大核心应用

1、定义操作标准

2、表示能力

3、在分布式开发中暴露远程服务方法(设计的概念比较庞大)rest架构,必须会

接口是在类上的抽象

设计类之前先设计接口

课时70 接口的定义与使用(工厂设计模式)

(重要!!)

中间人,避免和对象直接接触

主方法是客户端,对于程序的修改不应该影响到客户端的代码

interface IFruit {

publicvoid eat() ;

}

class Apple implements IFruit {

publicvoid eat() {

System.out.println("吃苹果");

}

}

class Orange implements IFruit {

publicvoid eat() {

System.out.println("吃橘子");

}

}

class Factory {

//不需要factory产生实例化对象

publicstatic IFruit getInstance(String cmd) {

if("apple".equals(cmd)) {

returnnew Apple();

}

if("orange".equals(cmd)) {

returnnew Orange();

}

returnnull;

}

}

public class TestDemo {

publicstatic void main(String[] args) {

if(args.length != 1) {

System.exit(1);

}

IFruitfruit = Factory.getInstance(args[0]);

fruit.eat();

}

}

接口,有子类,有工厂类,工厂类获取子类对象

 

课时71 接口的定义与使用(代理设计模式)

必须学会

背诵结构!

Proxy

两个子类共同实现一个接口,一个子类负责真实的业务实现,另外一个完成辅助真实主题的操作

接口:核心目的

子类1:核心实现

子类2:代理实现

子类2调用子类1

加上工厂模式

记住代理模式的结构

课时72 接口的定义与使用(抽象类与接口的区别)

优先选择接口,开发

抽象类可以加普通方法

抽象类:

abstract class

抽象方法+普通方法+全局常量+全局变量+属性+构造方法

可以使用各种权限

子类使用extends继承抽象类

一个抽象类可以实现若干个接口

单继承

接口:

interface

抽象方法+全局常量

只能选择public权限

子类利用implements继承接口

一个接口不能继承抽象类,但是可以通过extends继承多个父接口

一个子类可以继承多个接口

实际开发中,抽象类设计比接口复杂

要求掌握:定义接口+实现子类

结构体:

类,对象,抽象类,接口

现阶段看见接口,先考虑创建子类

1、开发先考虑接口,避免但集成的局限

课时73 匿名内部类

匿名类:抽象类和接口上实现

普通类也可以写匿名内部类,但是不要使用,因为继承要求都是抽象类

暂时不要话费过多精力在匿名内部类上

jdk1.8 匿名内部类有了改进

课时74 Object类(Object类简介)

重要的操作类,java除了Object类之外都是有继承关系的,默认继承Object父类

以下两种类的定义效果一致:

class Message {}

class Message extends Object{}

例子

开发过程中,Object类是参数的最高统一类型。

Object本身自带的一些方法:

提供无参构造:所有的子类实例化的时候需要调用父类的无参构造

(必须把Object中的方法都掌握)

toString 取得对象信息

equals 对象的比较

课时75 Object类(取得对象信息)

直接输出对象的时候是对象的地址编码

默认输出对象调用的就是toString方法

得到对象地址(所有对象都具有的特征)

子类可以复写toString方法

public String toString() {

}

toString的核心目的在于取得对象信息。替换了简单java类中的getInfo方法

String是作为信息输出的重要数据类型,所有的数据类型和String一起的时候,使用+号变为字符串链接

而对象要变成字符串,要使用toString方法

结论:字符串是王道,都会向string转型

课时76 Object类(对象比较)

使用equals()方法

String类中复写了equals()

开发过程中,使用equals进行对象比较。

对象比较开发过程中比较少用

课时77 Object类(接收引用数据类型)

Object可以接受任意的对象

可以接受所有的引用数据类型(数组,接口,类)

例子1:数组

例子2:接口,Object接受接口对象是强制规定

参数统一

【笔记】阿里云大学Java面向对象开发课程笔记01-77课时相关推荐

  1. [阿里云大学][Java面向对象开发][课程笔记][17-42课时]

    课时17 数组的定义与使用(数组转置) 首尾交换 1. 新定义一个空数组,然后把原数组的值从后到前存入新的数组 问题:开辟了两块相同的堆内存空间,造成浪费 2. 在原数组上反转 计算数组长度/2,交换 ...

  2. 阿里云大学 Java编程入门(一)Java语言简介

    Java语言简介 一.Java语言简介 1.1 认识Java(Java发展简介) 1.2 Java语言特点 1.3 Java可移植性 本系列内容为阿里云大学 java学习路线里的内容 阿里云大学 ja ...

  3. 阿里云大学-Java开发初级

    下面的数据声明及赋值哪一个是正确的?( D ) A. float f = 1.3; B. char c = C. byte b = 257 D. int i = 10 MyBatis如何配置类型简称别 ...

  4. 利用阿里云搭建Java Web开发环境

    安装jdk 查看yum源中的jdk版本 yum list java* 安装jdk1.8 yum -y install java-1.8.0-openjdk* 查看java的版本 java -versi ...

  5. 阿里云【名师课堂】Java面向对象开发57 ~ 59:覆写

    阿里云[名师课堂]Java面向对象开发57 ~ 59:覆写 57:方法覆写 概念 访问权限 重载和覆写的区别 58:属性覆盖(了解) 59:super关键字 调用父类方法 调用父类属性 super与t ...

  6. 阿里云【名师课堂】Java面向对象开发2:面向对象简介

    阿里云[名师课堂]Java面向对象开发2:面向对象简介 编程语言发展阶段 编程语言发展阶段 面向机器语言:汇编语言 面向过程语言:C语言.FORTRAN等 面向对象语言:Java等 面向过程的核心是编 ...

  7. 阿里云部署Java开发环境

    阿里云部署Java网站和微信开发调试心得技巧(上) 本文主要是记录在阿里云服务器从零开始搭建Java执行环境并且部署web project的过程,方面以后查阅. 一.申请阿里云服务器 购买阿里云服务器 ...

  8. java公社博客_Java面向对象开发学习笔记(一)

    Java面向对象开发 共105课时 课时1 面向对象简介 面向对象是一种程序设计方法,但是并不是所有开发者都认同面向对象,因为很多开发者认为面向对象过于复杂,所以更多人愿意使用函数式编程. 面向对象的 ...

  9. 阿里云趣味视觉AI训练营学习笔记Day 5

    阿里云趣味视觉AI训练营学习笔记Day 5 学习目标 学习内容 前言 一.创建人像卡通化应用 二.应用配置 三.后端服务开发部署 四.小程序前端开发 阿里云高校计划,陪伴两千多所高校在校生云上实践.云 ...

最新文章

  1. $.ajax 的async参数在crossdomain跨站下的问题
  2. 【转帖】配置管理计划(CM Plan)
  3. onvif规范 中文介绍
  4. [html] 如何禁止input输入的历史记录
  5. 负载均衡会话保持技术、原理、产品(以F5为例)
  6. internetreadfile读取数据长度为0_Go发起HTTP2.0请求流程分析(后篇)——标头压缩
  7. 微信又可以发520红包,还新增情人节“撒狗粮”状态:律师提醒注意
  8. 针对自动化测试的23种Node.js优秀实践
  9. 马氏距离(Mahalanobis Distance)与欧式距离
  10. python中关于requests里的timeout()
  11. 《守望先锋》中网络脚本化的武器和技能系统
  12. [软件补丁]VS6 sp6补丁下载
  13. html中怎么引用jquery
  14. 2020 对自己好一点之新 Mac Book Pro 环境的安装
  15. oss :Request has expired.
  16. 小白终是踏上了这条不归路----小文的mysql学习笔记(1)
  17. JAVA调用有道API接口对数据库中的中文语句进行翻译
  18. Java常用集合List、Map、Set介绍以及一些面试问题
  19. 中国空间科学技术 参考文献
  20. Cause: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, \“wname\“)\r\n\ta

热门文章

  1. 安装opencv踩坑笔记
  2. JT∕T 905 -2014 出租汽车服务管理信息系统的相关协议研究
  3. WiseBrowser 1.0震撼上市 创造移动浏览器巅峰神话
  4. 【error LNK1104】【无法打开文件opencv_core345d.lib 解决思路】
  5. 互联网思维(二)——流量时代,私域为王
  6. 高绩效团队的“八个一”特征
  7. 专享策略02 | 套利策略-自动换仓-出场加速
  8. rocketmq docker
  9. 解决SpringBoot项目中遇到的数据库连接yml文件配置问题
  10. Python图像处理(6):分离土壤与植物