三、面向对象(高琪java300集+java从入门到精通笔记)
面向对象基础:
对象的进化史
基本数据类型阶段 数据少 无数据管理时代
数组 数据多了,将同类型的数据放到一起 弱管理
结构体 数据多了,数据复杂了。将不同类型的数据放到一起 强管理
对象 数据多了、类型复杂了、行为复杂了。将不同类型的数据放到一起 超强管理
前三个:面向过程 数据和行为是分开的 行为去组织数据
最后一个:面向对象 通过对象组织数据
对象和类:
对象是具体的,类是抽象的(类是对对象的共性的总结)。类也是一个模版,通过类这个模版我们也可以new对象。
对象分为两部分:
静态部分:属性→成员变量
动态部分:行为→方法
类是封装了对象的属性和行为的载体
定义类:
public class 类名 {
//属性
private(建议) 数据类型 属性名; //建议增加相应的getter、setter方法
//方法
(往往是对上面数据的操作,建议static修饰,方法很类似于面向过程中的函数。面向过程中,函数是最基本单位,整个程序由一个个函数调用组成。面向对象中,整个程序的基本单位是类,方法是从属于类和对象的
方法的调用方式:
对象名.方法名(实参列表)
return 语句终止方法的运行并指定要返回的数据
Java中进行方法调用中传递参数时,遵循值传递的原则(传递的都是数据的副本):
基本类型传递的是该数据值的copy值。引用类型传递的是该对象引用的copy值,但指向的是同一个对象)
//构造方法
}
构造方法(作用:new对象和初始化属性):
方法名必须跟类名保持一致
无返回类型(返回本类的对象)
通过new来调用(实例化对象)
无参构造器问题:
如果我们没有手动定义构造器,系统会自动为我们添加一个无参的构造器
如果我们自己定义了构造器,系统就不会为我们添加无参构造器
构造方法的第一句总是:super(写不写都是这句),即调用直接父类的构造方法。
(若是构造方法的第一行代码没有显式的调用super(…)或者this(…))
- 有继承关系的构造方法调用的顺序
Dog—继承—>Animal—继承—>Object
流程就是:先向上追溯到Object,然后再依次向下执行(new)类的初始化块(构造方法用于对象的初始化!静态初始化块,用于类的初始化操作!)和构造方法,直到当前子类为止。
注:静态初始化块调用顺序,与构造方法调用顺序一样,上溯到Object类,先执行Object的静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。
- 有参构造方法不能被自动调用,只能依赖super显式地调用。
方法的重载(Overload):
两同(同一个类、同一个方法名)三不同(参数列表不同:;类型、个数、顺序)
返回值不同,构成重载吗? No
形参名称不同,构成重在吗? No
内存分析:Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。
栈的特点如下:
1.
栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
2.
JVM为每个线程创建一个栈(多个线程多个栈),用于存放该线程执行方法的信息(实际参数、局部变量等)
3. 栈属于线程私有,不能实现线程间的共享!
4. 栈的存储特性是“先进后出,后进先出”
5. 栈是由系统自动分配,速度快!栈是一个连续的内存空间!
堆的特点如下:
1. 堆用于存储创建好的对象(new执行完)和数组(数组也是对象)
2. JVM只有一个堆,被所有线程共享
3. 堆是一个不连续的内存空间,分配灵活,速度慢!
方法区(又叫静态区)特点如下:
1. JVM只有一个方法区,被所有线程共享!
2. 方法区实际也是堆,只是用于存储类、常量相关的信息!
用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】(代码一加载)、静态变量、字符串常量等)
class Computer {
String brand; //品牌
}
public class SxtStu {
//属性fieldsint id;String sname;int age;
Computer comp;//计算机
//方法
void study() {System.out.println("我正在学习!使用我们的电脑,"+comp.brand);
}
void play() {
System.out.println("我在玩游戏!王王者农药!");
}
//构造方法。用于创建这个类的对象。无参的构造方法可以由系统自动创建。
}
//程序执行的入口,必须要有
Javac Sxtstu.java ,java Sxtstu
public static void main(String[] args) {
SxtStu stu1 = new SxtStu();//创建一个对象stu1.sname = "张三";Computer comp1 = new Computer();comp1.brand = "联想";stu1.comp = comp1;stu1.study();}
}
注意:
先加载代码到方法区
main方法也是静态方法
变量是声明(赋值),对象是引用(new存放的是对象的内存地址)
new对象时调用构造方法,也是方法,要开辟新的栈帧(图中没画是因为对象创建完毕)
类是模板,调用构造方法来根据模板创建对象
stu和c1都是main方法中的局部变量
对象中的变量起初都是默认值(类的成员变量)
几个关键字:
this(本质:创建好的对象的地址
创建一个对象分为如下四步:
1. 分配对象空间,并将对象成员变量初始化为0或空
2. 执行属性值的显式初始化(方法区中的量赋值??)
3. 执行构造方法(this 可用于构造方法)
4. 返回对象的地址给相关的变量
):
1.普通方法中,调用本方法的对象。
void sing() {
}void eat() {this.sing(); // 调用本类中的sing();}
2.构造方法中,正要初始化的对象。如下
3.调用其他的构造方法
TestThis() {
System.out.println("正要初始化一个Hello对象");}TestThis(int a, int b) {// TestThis(); //这样是无法调用构造方法的!this(); // 调用无参的构造方法,并且必须位于第一行!this.a = a;this.b = b;}TestThis(int a, int b, int c) {this(a, b); // 调用带参的构造方法,并且必须位于第一行!this.c = c;}
4.this不能用于static方法中(this-对象 static-类信息)
super:
1.super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。(只能是public和protected)
- 使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。(与构造方法中super位置做对比)
static:
用它修饰的变量和方法,就变成了静态变量和静态方法。从属于类。通过类名即可调用。实际存储于方法区中。
- 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
2.
对于该类的所有对象来说,static成员变量(局部变量出错)只有一份。被该类的所有对象共享!!
3.
一般用“类名.类属性/方法”来调用。(也可以通过对象引用(不建议)对象.静态成员(是否静态易混淆)或类名(不需要实例化)访问静态成员。)
- 在static方法中不可直接访问非static的成员。
堆中对象(汽车)可以得到方法区中类(图纸)
垃圾回收机制(速学堂4.7-4.7.4)
两种无用对象(是没有任何变量引用该对象)情况:对象引用超过其作用范围
{
Example e=new Example();
}
- 将对象赋值为null
{
Example e=new Example();
e=null;
}
垃圾回收相关算法
- 引用计数法
堆中每个对象都有一个引用计数。被引用一次,计数加1.
被引用变量值变为null,则计数减1,直到计数为0,则表示变成无用对象。优点是算法简单,缺点是“循环引用的无用对象”无法别识别。
循环引用
public class Student {
String name;Student friend;public static void main(String[] args) {Student s1 = new Student();Student s2 = new Student();s1.friend = s2;s2.friend = s1; s1 = null;s2 = null;}
}
s1和s2互相引用对方,导致他们引用计数不为0,但是实际已经无用,但无法被识别。
2. 引用可达法(根搜索算法)
程序把所有的引用关系看作一张图,从一个节点GC
ROOT开始,寻找对应的引用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
内存泄漏:
1.创建大量无用对象
比如,我们在需要大量拼接字符串时,使用了String而不是StringBuilder。
String str = “”;
for (int i = 0; i < 10000; i++) {
str += i; //相当于产生了10000个String对象
}
- 静态集合类的使用
像HashMap、Vector、List等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放。
3.各种连接对象(IO流对象、数据库连接对象、网络连接对象)未关闭
IO流对象、数据库连接对象、网络连接对象等连接对象属于物理连接,和硬盘或者网络连接,不使用的时候一定要关闭。
4.监听器的使用
释放对象时,没有删除相应的监听器。
补充:
1.我们无权调用垃圾回收器。
System.gc()强制启动垃圾回收器,该方法只是通知JVM,并不是运行垃圾回收器。尽量少用,会申请启动Full
GC,成本高,影响系统性能。垃圾回收机制只能回收new创建的对象,否则用Object的protected方法finalize()。
package:
package必须位于非注释性第一句。
包名:域名倒着写
import:
引入外部的类
Import static 静态成员 :导入类的静态成员(主要是属性)
final:
修饰变量:常量(命名规范:全部大写,多个单词之间通过下划线隔开)
修饰方法:不能被重写 同private修饰 private final似乎可以被覆盖
修饰类: 不能被继承 所有方法都是final形式 成员变量可final/非final
面向对象的三大特征:
封装
通过private、default 、protected、public关键字实现属性或方法的封装。
注:其他包中的子类
“高内聚,低耦合”
1.一般使用private访问权限。
2.
提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头!)。
继承
通过extends 。两个好处:
代码重用
通过继承实现对现实世界更加准确的建模
类只有单继承,没有像C++那样的多继承
Java中类没有多继承,接口有多继承。
子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法???),
方法重写(Override)的要点(实现多态的必要条件):
1.“==”: 方法名、形参列表相同。
2.“≤
≤”:返回值类型和声明异常类型,子类小于等于父类(超类、基类、派生类等)。
3.“≥”: 访问权限,子类大于等于父类
Object类:
是我们所有类的根基类
toString (用来打印对象)
public String toString() {
return getClass().getName() + "\@" + Integer.toHexString(hashCode());
}
getClass()返回对象执行时的Class实例 final 不能被重写
getname()返回类的名称
默认会返回“类名+@+16进制的hashcode”。在打印输出或者用字符串连接对象时,会自动调用该对象的toString()方法
==、equals、hashcode
“==”比较的是两个对象的引用是否相同(基本类型则表示值相等,引用类型则表示地址相等即是同一个对象)在String
s1 = "chance"时
在new String(“chance”)时
- equals()比较的是两个对象的实际内容 ❌ 只是在String类中是
默认就是比较两个对象的hashcode
非String类(即Object中的equals)==和equals一样 都是比较引用地址,即对象
public boolean equals(Object obj) {
return (this == obj);
}
String类中被重写 这才是比较两个对象的实际内容
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
…方法将两个String对象拆分成字符数组,然后通过遍历字符数组中的每一个字符是否都相等,若相等,则返回true
否则返回false…
}
1.如果两个对象equals()相同,那么这两个对象的HashCode()一定也相同
equal()对比是绝对可靠的 效率低
2.如果两个对象的HashCode()相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置
所以解决方式是,每当需要对比的时候,首先用hashCode()去对比,如果hashCode()不一样,则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
- wait、notify、notifyAll final 不能被重写
多态(polymorphism):同一个方法调用,由于对象不同可能会有不同的行为
符合开闭原则(对扩展开放,对修改关闭)
- 多态是方法的多态,不是属性的多态(多态与属性无关)。
2.三个必要条件:继承、方法的重写、父类引用指向子类对象(向上转型,属于自动类型转换)
3.父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
class Animal {
**public** **void** shout() {System.out.println("叫了一声!");}
}
class Dog extends Animal {
**public** **void** shout() {System.out.println("旺旺旺!");}**public** **void** seeDoor() {System.out.println("看门中....");}
}
class Cat extends Animal {
**public** **void** shout() {System.out.println("喵喵喵喵!");}
}
public class TestPolym {
**public** **static** **void** main(String[] args) {Animal a1 = **new** Cat(); // 向上可以自动转型//传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。animalCry(a1);//a1为编译类型,Cat对象才是运行时类型。Animal a2 = **new** Dog();animalCry(a2);//a2为编译类型,Dog对象才是运行时类型。//编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。// 否则通不过编译器的检查。
弊端,就是无法调用子类特有的功能,我不能使用父类的引用变量调用Dog类特有的seeDoor()方法
Dog dog = (Dog)a2;//向下需要强制类型转换dog.seeDoor();}// 有了多态,只需要让增加的这个类继承Animal类就可以了。**static** **void** animalCry(Animal a) {a.shout();}
父类引用做方法的形参,实参可以是任意的子类对象,可以通过不同的子类对象实现不同的行为方式。
/\* 如果没有多态,我们这里需要写很多重载的方法。\* 每增加一种动物,就需要重载一种动物的喊叫方法。static void animalCry(Dog d) {d.shout();}static void animalCry(Cat c) {c.shout();}\*/
}
向下转型时用到 myobject(父类对象引用) instanceof (父类对象是否为子类的实例)
ExampleClass(子类)
动态绑定机制(java慢,现找,下一步做什么不知道,做的时候再说)、静态绑定:
抽象类(abstract):
包含抽象方法的类,一定是抽象类。
抽象类不能被new(实例化)。
抽象类可以包含:普通方法、成员变量、构造方法(不能用,不能new,只能用来被子类调用。)。
类不能用final修饰
方法只能用public修饰
如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类
接口:
interface
类实现接口:implements 可以实现多个接口
接口可以多继承
interface Inter implements Inter1,Inter2{ //Inter、Inter1、Inter2都为接口
}
- 接口定义的一组规范!实现现实世界中这样的逻辑::如果你是…则必须能…
定义接口的详细说明:
1.
访问修饰符:只能是public(仅限于接口在与其同名的文件中被定义)或默认。
2. 接口名:和类名采用相同命名机制。
3. extends:接口可以多继承。
4.
全局常量(一般是不会在接口中使用):接口中的属性只能是常量,总是:public
static final 修饰。不写也是。
5. 公共的抽象方法:接口中的方法只能是:public abstract。
省略的话,也是public abstract。
要点
1. 子类通过implements来实现接口中的规范。
2. 接口不能创建实例,但是可用于声明引用变量类型。
3.
一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
4.
JDK1.7之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
5. JDK1.8后,接口中包含普通的静态方法。
区别:
- 普通类:具体实现
2. 抽象类:具体实现,规范(抽象方法) 有main 有构造器???
3. 接口:规范!(全部抽像)接口是抽象类的特殊化 比抽象类更加“抽象”
无main 无构造器???
对于遵循某个接口的抽象类,可以不实现该接口中的抽象方法
内存机制:
栈
存放局部变量
不可以被多个线程共享
空间连续,速度快
堆
存放对象
可以被多个线程共享(所以有资源冲突问题 每个对象都有锁)
空间不连续,速度慢。但是灵活
方法区
存放类的信息:代码、静态变量、字符串常量等
可以被多个线程共享
空间不连续,速度慢。但是灵活
垃圾回收器(GC Garbage Collection):
程序员不能调用垃圾回收器。但是可以通过System.gc()建议回收。
Finallize(释放对象池资源):一般也不用调
递归算法:
- 递归头:什么时候不调用自己
通属性、构造方法、普通方法。
5. JDK1.8后,接口中包含普通的静态方法。
区别:
- 普通类:具体实现
2. 抽象类:具体实现,规范(抽象方法) 有main 有构造器???
3. 接口:规范!(全部抽像)接口是抽象类的特殊化 比抽象类更加“抽象”
无main 无构造器???
对于遵循某个接口的抽象类,可以不实现该接口中的抽象方法
内存机制:
栈
存放局部变量
不可以被多个线程共享
空间连续,速度快
堆
存放对象
可以被多个线程共享(所以有资源冲突问题 每个对象都有锁)
空间不连续,速度慢。但是灵活
方法区
存放类的信息:代码、静态变量、字符串常量等
可以被多个线程共享
空间不连续,速度慢。但是灵活
垃圾回收器(GC Garbage Collection):
程序员不能调用垃圾回收器。但是可以通过System.gc()建议回收。
Finallize(释放对象池资源):一般也不用调
递归算法:
递归头:什么时候不调用自己
递归体:什么时候调用自己
三、面向对象(高琪java300集+java从入门到精通笔记)相关推荐
- 【160天】尚学堂高琪Java300集视频精华笔记(129)
明天开始,专栏增加一个黑马程序员的课程更新. 其它容器收尾讲解 队列Queue与Deque(单向队列与双向队列) Enumeration(较老的接口,JDK1.5前使用频繁,维护旧系统会用到) Has ...
- java高淇_高淇java300集JAVA常用类作业
一.选择题 1. 以下选项中关于int和Integer的说法错误的是( B D).(选择二项) A.int是基本数据类型,Integer是int的包装类,是引用数据类型 B.int的默认值是0,Int ...
- 尚学堂 高琪JAVA300集第十一章作业 编程题答案
本人 JAVA初学者 在寻找这一方面的答案时没有看见 ,本着分享的精神 自己做了出来 也就传上来了 水平有限 存在有错的地方或者改进的方法 ,望大佬们可以提出 万分感谢. 1.1. 设计一个多线程的程 ...
- Java从入门到精通笔记20230106--百钱百鸡引出的疑问
一.5文钱可以买1只公鸡,3文钱可以买1只母鸡,1文钱可以买3只雏鸡,现在用100文钱买100只鸡,那么公鸡.母鸡.雏鸡各有多少只? 1.Python写法 首先在Python刷题时遇到过,实现起来相对 ...
- java从入门到精通_想要开始学java?你要的java从入门到精通布列如下!
java从入门到精通,让我来告诉你! 毫无疑问,java是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握java看似是一件十分困难的事.其实,只要掌握了科学的学习方法 ...
- 详细:JAVA从入门到精通视频教程,后台学习历程
详细:JAVA从入门到精通视频教程,后台学习历程 ==基础部分 由于百度分享有时效性 想要免费资源的请加645969403 1.java基础:高琪java开发300集 链接:https://pan.b ...
- java从入门到精通第四版明日科技书籍简介及下载
Java从入门到精通(第4版)(附光盘) 平装 – 2016年10月20日 <Java从入门到精通(第4版)(附光盘)>从初学者角度出发,通过通俗易懂的语言.丰富多彩的实例,详细介绍了使用 ...
- java从入门到精通_Java入门到精通、学习路线、就业方向、薪资及前景分析(上篇)...
今天就大家最关心的Java热门问题进行简要分析,希望能对想要学习或是正在学习Java的小伙伴能够有所帮助~(大家多多关注呦~) 一.首先我们要了解Java是什么? 好学吗? Java是一种广泛使用的计 ...
- Java从入门到精通十一(javaIO流)
Java从入门到精通十一(javaIO流) IO引入 字节流和字符流(一些说明) 字节流没有用到缓冲区并不是没有用到内存 为什么输入流是读数据,而输出流是写数据? 字节流说明 字节输入流读数据的方法 ...
- java从入门到精通二十三(Servlet)
java从入门到精通二十三(Servlet) Servlet 说明 Servlet初步入门尝试 Servlet生命周期 Servlet方法说明和体系结构 方法说明 体系结构说明 一些优化封装 urlP ...
最新文章
- 算法马拉松13 A-E解题报告
- [RabbitMQ]RabbitMQ概念_四大核心概念
- SparkSql之DataFrame操作
- 【Elasticsearch】ES写入满排查思路-内存溢出
- 让电脑代码满屏飞_程序员想让你的电脑死机,需要多久?
- Flyod和Warshall
- codeforces 360B
- 微信小程序云开发 实时地图显示
- 淘宝技术发展(Oracle/支付宝/旺旺)
- 网络安全基本属性和STRIDE
- 硬盘测试软件黑屏,教你怎么使用硬盘检测修复工具教程
- 从一到无穷大 #2 优雅的感知与处理Elephant Flows
- 嵌入式静态显示与动态显示
- 问!—— 斜杆/ 和 反斜杠\ 的区别
- java 程序设计 第八版,java语言程序设计第八版答案
- Python中常用的数据结构---哈希表(字典)
- Java游戏服务端开发系列文章
- Coding and Paper Letter(四十五) 1
- Win10怎么在桌面添加备忘录 Win10桌面添加备忘录方法
- 深刻理解 Linux 进程间七大通信(IPC)
热门文章
- linux 创建gpt分区,parted创建GPT分区
- 儿童节html模板,六一儿童节作文350字满分模板
- python网页搜索脚本_bing搜索引擎子域名收集(Python脚本)
- weblogic增大线程数
- iPhone7 plus分辨率行不行
- html视频播放后自动跳转到页面,在html5视频中跳转到currentTime后自动播放(autoplay after jump to currentTime in html5 video)...
- 【Python】Pymyql模块的execute()总结
- 墨羽卿画第二章第7节:跬步
- 直播讲座:时序数据库 Apache IoTDB 的核心技术与应用
- LINUX论坛快速搭建(小白版)