OOP
------
Oriented object program,面向对象编程。
OOA
------
Oriented object analyze,面向对象分析。
OOD
------
Oriented object design,面向对象设计
一切都是对象.
面向过程的.
----------
c:
entity:实体。
new 关键字,创建对象
理解面向对象
将功能封装进对象,强调具备了功能的对象
不断使用对象,创建对象,再使用对象
--------------------------------------
面向对象的特征
1.封装
2.继承
3.多态
对象
--------
切实存在的个体。
类
------------
物以类聚,人以群分。
人找人,虾找虾。
对现实事务的软件抽象。
类成员
----------
1.成员变量(事物的属性)
属性
有默认初始化值:
数值类型的基本数据类型默认值是0
对象或引用类型的就是null空值
存放在堆区
定义在类中,在整个类中都可以访问,不受顺序影响
随着对象的建议而建立,存在于对象所在的堆内存中。
2.成员函数(事物的行为,能做什么,)
方法.
如果是静态的方法,不用创建对象就可以拿到;如果一定要通过创建对象拿到方法就需要占用内存空间(不是必须就不要开辟内存空间造成浪费)
3.定义方式
class 类名{ 成员变量; 成员函数} //每个单词首字符大写,特殊字符只能以$_开头。
4.对象的造创
局部变量
-----------
定义在方法或者语句中。
没有默认的初始化值,如要访问局部变量必须初始化,否则报异常;
存放在栈中。
所在范围结束后,空间自动释放。生存周期只在所在成对大括号内(方法内)
堆
----------
数组和对象在堆中。
栈
-----------
方法在栈中 先进后出 main方法首先压入栈
压入的是方法针,在一针内有局部变量,这个局部变量周期仅在这一针内有效。
push 压栈(载入方法) pop 弹栈(弹出方法)
方法运行完成后,就弹出
堆区和栈区都是在程序运行时才会生成
示例及说明:创建对象 和使用对象
-----------------------------------
/**
*定义一个类示例
*/
class ClassDemo1{
public static void main(String[] args){
//创建一个Person的对象,这里共有三个过程:
//1.创建局部变量,
//2.开辟内存空间(在堆中创建对象),产生内存地址。
//3.将内存地赋值给第1步的局部主量中,局部变量只是引用内存地址。
Person p = new Person(); //p为局部变量
//使用对象,给对象的属性赋值
p.height = 180 ;
//调用对象的方法 .加方法名,如有参数在括号内输入参数
p.run();
//使用属性
System.out.println(p.height);
}
}
/**
*定义一个人的类
*/
class Person{
//成员变量:属性(property):字段(field)
int height ; //身高
int weight ; //体重
int age ; //年龄
//定义一个成员函数:方法 run跑的方法,人是可以跑的
public void run(){
System.out.println("run...");
}
}
-------------------------------------------
堆栈溢出指的是栈溢出
-------------------------
StackOverflow:栈溢出
堆比栈大
--------------------------
//负值数组大小异常(NegativeArraySizeException),数组长度过长被截断,首位符号位为1,变成负数,导致数组大小异常
NegativeArraySizeException
Exception in thread "main" java.lang.NegativeArraySizeException
at StackHeapDemo.main(StackHeapDemo.java:4)
-----------------------------------------------------
//内存不足错误(OutOfMemoryError)
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exce
eds VM limit at StackHeapDemo.main(StackHeapDemo.java:4)
--------------------------------------------------------
double d ;
long
1byte
1024 = 1K
2^10 = 1024
1kb = 1024 byte
1mb = 1024k byte
1gb = 1024m byte = 1024 x 1024 x 1024 ;
1tb = 1024g byte
1pb = 1024t byte
1eb = 1024pb
1zb = 1024eb
1yb = 1024zb
1nb = 1024yb
jvm堆栈初探
------------------
在命令行下执行
1.jps [-v] //查看运行的java进程:
2.jmap -heap pid //查看指定java进程的堆空间
//jmap 也是jak自带工具
//linux 下切换为root
3.java中对象和数组位于堆内存中,局部变量、函数参数等位于栈内存中
4.栈默认空间大小是1m。
5.堆默认空间大小是1/4物理内存.
java VM调整堆大小
java -X //查看java非标准输出帮助
java -Xmx100m //设置jvm的堆空间最大值
java -Xms100m //设置jvm的堆空间初始值
堆溢出
---------------------------
//堆溢出,使用整形最大值作为数组长度,直接导致堆溢出
//byte[] arr0 = new byte[Integer.MAX_VLAUE];
JVM虚拟机调优,调堆的初始化和最大值的空间大小;这两个值通常设置成一样的大小。
例:
//内存不足错误(OutOfMemoryError)
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exce
eds VM limit at StackHeapDemo.main(StackHeapDemo.java:4)
=======================================================
栈溢出(StackOverflowError)
-------------------------------------
例://通过死循环调用方法,导致栈溢出演示,
//当需要调用过多的方法时,如果出现溢出可调整栈空间大小,但一般很少调整此项,演示中的死循环为程序BUG。
class StackHeapDemo{
public static void main(String[] args){
out(1);
}
public static void out ( int i){
System.out.println(i);
out(i + 1);
}
}
//执行结果
11400
11401
11402
Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.ext.DoubleByte$Encoder.encodeLoop(Unknown Source)
at java.nio.charset.CharsetEncoder.encode(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at StackHeapDemo.out(StackHeapDemo.java:15)
at StackHeapDemo.out(StackHeapDemo.java:16)
java VM调整栈大小(很少需要调整栈方法)
------------
java -Xss2m //设置Java线程堆栈大小
栈默认空间大小是1m。
匿名对象:
不创建变量,直接创建对象,不需要通过变量保持
-------使用形式---------
1.new Person().run(); //匿名对象可直接调用对象中的属性和方法,只访问一次。
2.run(new Person()); //作为参数进行传递
封装(Encapsulation)
-----------
将部分成员隐藏起来,外界只能通过其他方式进行方法。
使用private进行修饰,保证安全性。
好处:
1.将变化隔离;
2.便于使用;
3.提高重用性 ;
4.提高安全性
封装原则:
1.将不需要对外提供的内容都隐藏起来
2.把属性都隐藏,提供公共方法对其方问
private : 私有的
1.修饰符;
2.用于修饰成员变量和成员函数;
3.被私有化的成员只能在本类中有效;
4.常用之一:将成员变量私有化,对外提供set(修改)和get(获取)方法对其访问,提高数据访问安全性。
public : 公有的
private 和public的常用方法
------------------------
一个类的中属性一般都是私有的,防止非法访问,然后通过公有的方法进行修改属性,经过方法处理后,可以有效管理修改属性的权限。
这种方法就是典形的一种封装形式。
常用方法命名 (动词加名称,首字母小写,后面单词首字母大写)
--------------------------------
获取开头单词用 get 例:getMoney
修改开头单词用 set 例:setMoney
构造函数
--------
1.函数名和类型相同
2.不用定义返回值类型
3.没有返回值.
创建之后肯定返回的是该类的对象,所以无需设置返值
4.如果类未定义构造函数,jvm将会分配一个空构造函数。
如果类定义了构造函数,jvm将不会分配空构造函数,必须自己定义空构造函数
5.作用:给对象进行初始化。
6.可以重载:函数名一样, 参数不一样
7.创建对象时,就需要指定构造函数,按参数类型判断使用哪个构造函数
Car c1 = new Car(); \\无参创建
Car c2 = new Car("white"); \\传参创建,参数可以有多个
构造代码块
----------
1.创建对象时调用.(可以有多个构造代码块,)
2.构造函数之前。
3.如果所有构造代码块有相同的代码,可以将这部分代码写入构造代码块中。
4.
对象创建过程
-----------
0.静态代码块
从上到下按序执行。
1.构造代码块
从上到下按序执行。
2.构造函数
3.成员变量
a.color = null ;
b.color = "black" ;
c.构造代码块
d.构造函数.
4.
类成员组成 及 相互关系
------
1、成员变量
2、成员函数
3、构造函数
4、构造代码块
5、局部代码块(包含在函数内部,仅函数内部有效)
6、静态代码块:在类加载期间执行,而且只执行一次,通常是完成一些初始化工作,就是所有对象都有同样的初始化过程,例如:连接数据库
7、静态成员之间可以互相访问,按序执行。
8、静态成员不可以访问非静态成员。
9、非静态成员可以访问静态成员。
10、静态成员通过类访问(和对象无关 访问方式:类名.静态成员名)。
11、静态方法中不可以用this super关键字
12、静态方法只能访问静态成员;
JVM运行后,各区域加载顺序 方法区、栈区、堆区
----------------------------------------------------------------------------
方法区:静态成员
栈 区:方法 、 局部变量
堆 区:数组 、 对象
javabean
---------
在计算机专业术语中,很多单词是专业用词,是不需要翻译的。
pojo :plain old java object 普通古老的JAVA对象
pojo指的就是最标准的java类,一般针对一些名称,这些名词用术语来讲又叫实体类。
例
class Dog{
private String color ; //成员变量是私有的
public String getColor(){ //并有成员变量对应的 读取get 、设置 set的 方法
return color ;
}
}
this.xxx
-------
指向对象自身的引用,类似成员变量,使用private修饰。
静态方法不可以使用this。
this() this (构造函数的参数)
-------
访问当前类的构造函数。(用于调用自己类中的)
this()的调用必须是第一条语句。
为了构造函数的重用(在构造函数中引用其他构造函数时,在第一条语句,可以使用this引用其他构造函数)
super() 在构造函数中使用
-------
1.访问超类的构造函数。(用于调用父类(超类)的空构造函数,如果没有见第4条)
2.必须是第一行代码。
3.构造函数的首行要么是this(),要么是super(),默认是super();
4.如果父类无空构造函数,子类的第一行super调用的就是父类的空构造,因为没有了空构造调不出来了,两种解决方式:1给父类加空构造函数;2就需要在子类中的空构造函数中使用super()指定超类的构造函数 super(参数))
例:-------------------------------------------
//定义一个动物类
class Animal{
String color ;
int height ;
//这里没有Animal的空参的构造函数,只有一个带参的构造函数
public Animal (String color ){
this.color = color ;
}
}
//狗类
class Dog extends Animal{
//因为Animal父类的空构造函数已没有了,需要使用super(参数) 指定一个父类的构造函数
//在当前类中创建一个空构造函数,用super(参数) 来指定父类的一个存在的构造函数;
public Dog(){ //创建一个子类的空构造函数
super("white"); //用super加参来指定父类的构造函数
}
}
class Jing8 extends Dog{
public Jing8(){
super();
}
String owner ;
}
-----------------------------------------------------------
5.每个空构造函数第一行都有一个super,只是省略掉了。
super() 与 super.xxx 是不同的
super.xxx
----------
1.访问超类的成员。
例说明:
超类 A1 有 run() 方法
父类A2(A1的子类) 也有 run()方法
子类A3(A2的子类)调用run()方法 只调用父类的(如果想要同时调用到超类及父类的可以在父类A2中的run()方法中加上 super.run() 来调入超类A1中的run()方法)这样A3在调用run()方法时,就会同时调用A1和A2中的run()方法.
2.当使用super.xxx调用方法时,指的是父类对象的一个引用,可以不用写在第一行
super关键字简要介绍
super和this的用法相像
this代表本类对象的引用
super代表父类的内存空间标识
当子父类出现同名成员时,可以用super进行区分
子类要调用父类构造函数时,可以使用super语句。
函数覆盖 (成员变量是不可以被覆盖的)
---------
(当父类的方法与子类的方法相同时,以子类方法的行为为准)
1.overwrite
重写
复写
2.只有在继承的时候才有重写。
3.private方法不可以覆盖。
继承概述
1、多个类中存在相同属性和行为时,将这些内容抽出到单独的类中,那么多个类就不用再定义,只要继承那个类即可
2、多个类称为子类,单独这个类称为父类或超类
3、子类可以直接访问父类非私有属性和行为
4、通过 extends 关键字让类与类之间产生继承关系
class SubDemo extends Demo{ }
5、继承的出现提高了代码的复用性,
6、让类与类之间产生了关系,提供了多态的前提。
继承
------
1.extends
2.类只支持单重继承
3.支持多层继承.
多态:
-------------------
可以简单从字面理解,多种状态,多种形态
成员函数
--------
成员变量 (相比成员函数重要)
--------
1.因为变量是最基础的数据,函数只是一个过程
2.最基础的数据是最重要的,所以在继承中是不能被覆盖的。