马士兵java基础笔记 pdf版 面向对象部分
![马士兵java基础笔记 pdf版 面向对象部分](https://img.360docs.net/img20/0zk2kxv5mzvd87pjker-01.webp)
![马士兵java基础笔记 pdf版 面向对象部分](https://img.360docs.net/img20/0zk2kxv5mzvd87pjker-e2.webp)
一面向对象设计思想
◆面向对象设计思想是,从现实世界中客观存在的事物出发构造软件系统,并在系统的构
造中尽可能运用人类的自然思维方式。
◆面向对象更加强调运用人类在日常思维逻辑中经常采用的思想方法与原则,如抽象、分
类、继承、聚合、多态。
◆对象用计算机语言对问题与中事物的描述,对象通过属性(attribute)和方法(method)来分
别对应事物所具有的静态属性和动态属性。
◆类是用于描述同一类型的对象的一个抽象的概念,类中定义了这一对象所因具有的静态
和动态属性。
◆类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
◆类(对象)之间的关系:
1.关联关系:映射到代码一个类的方法里面是另外一个类的对象,我的方法的参数是
你这个类的对象
2.继承关系:什么什么是什么
3.聚合关系
聚集:谁谁是谁的一部分。组合:咱们俩密不可分!
4.实现关系:
5.多态
总结:
●考虑问题里面有哪几个类,哪几个对象;找名词
●每种类有哪些属性和方法;
●类和类之间的关系。
二Java与面向对象
◆对象是Java的核心,在Java中“万事万物皆对象”。
◆对象可以看成是静态属性(成员变量)和动态属性(方法)的封装体。
◆类是用来创建同一类型的对象的模板,在一个类中定义了该类对象所具有的成员变量以
及方法。
◆为什么用对象?
1)Reusable
2)Extensiblity
3)维护和替换更加方便。
三Java中面向对象内存分析
1.Java类的定义
2.成员变量(返回值输出之后也消失,返回值在栈中)
3.引用
Java语言中除基本类型之外的变量类型都称之为引用类型。
Java中的对象是通过引用对其操作的。
引用类型占两块内存,堆栈中的引用,对里面的对象
String s = new String(“aaa”);
s→[],s在栈中,”aaa”在堆里面。
4.对象的创建和使用
◆必须使用new关键字创建对象。
◆使用对象(引用).成员变量或来引用对象的成员变量。
◆ 使用对象(引用).方法或来引用对象的方法。 ◆ 同一类的每个对象有不同的成员变量存储空间
◆ 同一类的每个对象共享该类的方法。(方法是一段静态的代码,执行时再去内存分
配空间)。非静态方法是针对每个对象进行调用 class C { int i; int j; main() {
C c1 = new C(); C c2 = new C(); } }
栈
c1
c2
堆
XX
XX
c1.i
c1.j XX XX
c2.i
c2.j
5. 构造函数(构造方法)
● 使用new +构造方法,创建一个新的对象。
● 构造函数是定义在Java 类中的一个用来初始化对象的函数。 ● 构造函数没有返回值。 public class Person { int id; int age; Person(int _id, int _age) { id = _id; age = _age; }
public static void main(String[] args) {
Person tom = new Person(1, 25); } }
Stack
tom:XXX tom:XXX
_id:1_age:25Heap
id:1age:25
例子:
class BirthDate { private int day; private int month; private int year;
public BirthDate(int d, int m, int y) { //构造方法 day = d; month = m; year = y; }
public class Test{
public static void main(String args[]){ Test test = new Test(); int date = 9;
BirthDate d1= new BirthDate(7,7,1970); BirthDate d2= new BirthDate(1,1,2000)(1); test.change1(date)(4); test.change2(d1);(7) test.change3(d2);
public void setDay(int d) {
day = d;
}
public void setMonth(int m) {
month = m;
}
public void setYear(int y) {
year = y;
}
public int getDay() { //int表示返回值类型
return day;
}
public int getMonth() {
return month;
}
public int getYear() {
return year;
}
public void display() {
System.out.println(day + " - " + month + " - " + year);
}
}
System.out.println("date=" + date);
d1.display();
d2.display();
}
public void change1(int i){
(2)i = 1234(3);
}
public void change2(BirthDate b) {
(5)b = new BirthDate(22,2,2004); (6)
}
public void change3(BirthDate b) {
(8)b.setDay(22);(9)
}
}
new了一个test对象,堆里面有一个
int date = 9在栈里面;
new出了一个d1,指向了一个new出来
的对象;
new出了一个d2,指向了一个new出来
的对象;
调change里面一个i,形参分配一个空
间,形参等同局部变量,栈内存里面有
个值,方法调用叫做值传递!
所以i=9
指向完i=1234,date把值拷贝给i,i的值变了,date的值没变!依靠此方法改变基础变量不行。
change方法执行完毕,为此方法分配的局部变量消失,i已消失,date的值依然是9
change2,传进来的了一个BirthDate的引用(b),注意红线,所以b—>d1
刚开始,b执行d1执行的对象,但是new出来了一个新对象,b指向了新的对象
执行完之后,b这个局部变量消失了,堆里面的内存不是马上消失,垃圾收集器收集的时候才消失,但是栈里面的内容马上消失的!对象里面的值(d1)依然没有变!
change3,把d2传进来,b指向了d2指向的对象
b.setDay(22),把b指向的值改变了,这次真的变了!
方法执行完后,b消失,d2的值变了。
四. 方法重载
类中可以定义相同名字但参数不同的方法。
五. this关键字
this指向对象自身的引用。
◆在类的方法定义中使用this关键字代表使用该方法的对象的引用。
◆当必须指出当前使用方法的对象是谁时要使用this
◆有时使用this可以处理方法中成员变量和参数重名的情况
◆this可以看作是一个变量,它的值是当前对象的引用
public class Leaf(){
int i = 0;
Leaf(int i) {
this.i = i;
}
…main() {
Leaf lf = new Leaf(9);
}
} 注意这里有两个i。
六. static关键字
◆在类中,static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用
时被初始化,对于该类的所有对象来说,static成员变量只有一份。
◆用static声明的方法为静态方法,在调用该方法时,不会将对象的引用传递给它,所以
在static方法中不可方法非static方法。
●静态方法不再是针对某个对象调用,所以不能访问非静态成员。
◆可以通过对象引用或类名(不需要实例化)访问静态成员。类名.静态成员变量.
◆字符串也放在数据区
◆静态变量可以做计数用
◆不能在静态方法中调用非静态变量
public class Cat {
private static int sid = 0;
private String name;
int id;
Cat(String name) {
https://www.360docs.net/doc/241123253.html, = name; id = sid++;
}
public void info(){
System.out.println ("My name is "+name+" No."+id);
}
public static void main(String arg[]){ Cat.sid = 100;
Cat mimi = new Cat("mimi"); mimi.sid = 2000;
https://www.360docs.net/doc/241123253.html,();
}}
stack
heap
数据区
sid:100
id id
name name
"mimi"
mimi:xxx
name
数据区
sid:100
id id
name name
"mimi"
mimi:xxx
七. 包 import 和package
为便于管理大型软件系统中数目众多的类,解决类的命名冲突问题,Java 引入包
(package )机制,提供类的多重类命名空间 八. 类的继承和权限控制
◆ Java 中使用extends 关键字实现类的继承机制
◆ 通过继承,子类自动拥有基类的所有成员(成员变量和方法) ◆ Java 只支持单继承,不允许多继承
student
Person name
age
school
new 一个子类对象出来的时候内存的情况 ◆ 权限控制:
九. super 关键字
student:xx
Person name age super
this
十.继承中的构造方法
◆ 子类的构造过程中必须调用基类的构造方法
◆ 子类可以在自己的构造方法中使用super()调用基类的构造方法
● 使用this 调用本类另外的构造方法;
● 如果调用super ,必须写在子类构造方法的第一行 ◆ 使用子类的构造方法中没有显示的调用基类构造方法,则系统默认调用基类无参数的构
造方法。
◆如果子类构造方法中既没有显示调用基类构造方法,而基类中又没有无参的构造方法,
则编译出错。
十一. Object类与toString()方法,hashCode,equals方法
◆Object类中定义有public String toString()方法,其返回值是String类型,描述当前对象
的有关信息。
◆在进行String与其他类型数据的连接操作时(System.out.println(“info ” + person )),将自
动调用对象类的toString()方法。
◆可以根据需要在用户自定义类型中重新toString()方法。
public class toString {
public static void main(String[] args) { Dog d = new Dog();
System.out.println("d: " + d);
}
}
输出:
d: Dog@de6ced 相当于
public class toString {
public static void main(String[] args) { Dog d = new Dog();
System.out.println("d: " +
d.toString());
}
}
继承自Object,可以重写该方法。建议所有子类都重写此方法(Java API) getClass().getName() + '@' + Integer.toHexString(hashCode())
类名+ …@? + hash编码。
hashCode
对象
对象
对象
对象
对象
对象
java虚拟机,用一张表记录每个对象在什么位置上,这个表一般用哈希编码来记录,每个对象都有自己独一无二的哈希编码,根据编码可以找到相关对象,并可以找到对象的位置。
◆equals方法:提供定义对象是否“相等”的逻辑,对于任何非空引用值 x 和 y,当且仅
当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
◆Object的equals方法定义为:x.equals(y),当x和y是同一对象的引用时返回true,否则返
回false。
◆J2SDK提供一些类重新了Object的equals方法,比如String,Date等。比如String的
equals方法:将此字符串与指定的对象比较。当且仅当该参数不为null,并且是与此对象表示相同字符序列的String 对象时,结果才为true。
◆可以根据自己需要定义equals方法。
十二. 对象转型
◆ 一个基类的引用变量可以“指向”其子类对象。
◆ 一个基类的引用不可以访问其子类对象新增加的成员(属性和方法)
◆ 可以使用引用变量instanceof 类名,来判断该引用类型指向的对象是否属于该类或该类
的子类。
◆ 子类的对象可以当作基类的对象来使用称为“向上转型”,反之称为“向下转型”。
十三. 多态
◆ 动态绑定: 指在“执行”期间(而非编译期间)判断所引用的对象的实际类型,根据
实际的类型调用相应的方法。
class Animal { private String name; Animal(String name) { https://www.360docs.net/doc/241123253.html, = name; } public void enjoy() { System.out.println("Animal call......"); } }
class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c; } public void enjoy() { System.out.println("Cat call......"); } }
class Dog extends Animal { private String furColor; Dog(String n, String c) {
分析:
1. 执行第一步的时候:
Cat c = new Cat("catName", "blue"); 在栈里面分配一个Cat 的引用c ,堆里面分配Cat 对象,Cat 对象里有eyesColor 属性和父类成员(继承而来)。
2. 执行到第二步的时候: Lady l1 = new Lady("l1", c);
在栈里面分配一个Lady 的引用l1,堆里面分配Lady 对象,Lady 对象有name 成员和Animal 成员,初始时,Animal 成员指向了Animal 对象。
3. 执行到第三步时: l1.myPetEnjoy();
public void myPetEnjoy() { pet.enjoy(); }
里面有一个pet ,到底哪个pet ?方法存储在代码区,方法就是一段代码,代码段里有Animal 和Cat 的enjoy 方法代码,根据实际new 出来的类型,来判断enjoy 方法到底哪一个调!而不是通过引用类型(Animal 的
super(n);
furColor = c;
}
public void enjoy() {
System.out.println("Dog call......");
}
}
class Lady {
private String name;
private Animal pet;
Lady(String name, Animal pet) {
https://www.360docs.net/doc/241123253.html, = name;
this.pet = pet;
}
public void myPetEnjoy() {
pet.enjoy();
}
}
class Poly {
public static void main(String args[]) {
(1)Cat c = new Cat("catName", "blue");
Dog d = new Dog("dogName", "black");
(2)Lady l1 = new Lady("l1", c);
Lady l2 = new Lady("l2", d);
(3)l1.myPetEnjoy();
l2.myPetEnjoy();
}
} enjoy),动态绑定便是new的谁就是调用谁的方法,实际中找方法的时候,对象内部有一个enjoy方法,但是这个指针随new的对象而指向对象重写的方法。
◆多态存在三个必要条件:
●要有继承
●要有重写
●父类引用指向子类对象
十四. 抽象类final关键字
◆用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,
这个方法叫做抽象方法。
◆含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
◆抽象类不能实例化
◆抽象方法只需声明,而不需实现
◆final的变量值不能被改变
◆final的方法不能被重写
◆final的类不能被继承
比如String类,public final class String
十五. 接口
◆接口是抽象方法和常量值的定义和集合
◆从本质上讲,接口是一种特殊的抽象类,这种抽象类只包含常量和方法的定义,而
没有实现。
public interface Runner {
public static final int id = 1; //为什么要final,修正多个父类之间重复的成员变量,public void start();
public void run();
public void stop();
}
A.接口可以多重实现;
B.接口中声明的属性默认为public static final,也只能是public static final
C.接口中只能定义抽象方法,这些方法是public,也只能是public
D.接口可以继承其他接口,也可以添加新的属性和方法。
◆多个无关的类可以实现同一个接口
◆一个类可以实现多个无关的接口
◆与继承关系类似,接口与实现类之间存在的多样性