面向对象
面向对象:
java是一门面向对象的语言 这是基于面向过程而言的
例子:
写一个播放器的功能:打开 播放 暂停 关闭
面向过程的思想:
第一步:打开 第二步:播放 第三步:暂停 第四步:关闭
面向对象的思想:
分析对象:播放器
然后调用播放器的一系列行为:对象.行为()
使用类的方法或者属性 要先创建类的对象: 比如Test t=new Test();
类和对象的关系:
类:类就是描述了一组具有相同属性和行为的对象
类就好比“人”这个抽象的概念
人都有的行为:比如会 跑 跳 说话等等
人都有的属性:比如 名字 年龄 性别等等
对象: 对象是一种具体的概念,是类的一种具体的表现形式
比如说“人”里一个叫“张三”的人 这个“张三”具有“人”的所有行为和属性
1.从代码角度分析:
类就是代码的载体
2.从逻辑的角度分析:
类就是模版 对象就是模版制作出来的一系列真实的产品
类的全名称和简单名称??
全名称: 包名+类名
比如:com.guigu.test1.Person
简单名称: Person
如何创建对象:
1.用new 比如:Student student=new Student();
2.类的加载
可以把第一种的方法分为两步:
第一步:类的加载 加载到虚拟机产生一个对象 class形式
Class clazz= Class.forName("类的全名称");
第二步: 创建类的实例
clazz.newInstance();
java中其实存在指针 只是使用引用的概念代替了指针
this: 是java的内置对象
代表的是当前类的对象
类中可以出现: 方法 属性 构造方法 代码块 静态代码块 内部类
方法:
代表的是对象的行为
格式:
修饰符 返回值 方法名(参数){
要执行的代码
}
方法的所属:
要么属于类 即当方法被static修饰时
要么属于方法 即不被static修饰
java中的参数传递问题:
java中的参数传递都是值传递的,值传递就是把实际参数的副本传入方法内。
对于基本数据类型传递的是变量的值。
对于引用数据类型传递的是变量的引用,即对象在堆内存中的地址。
栈内存: 方法栈
对于所要运行的每个方法都会有一个栈内存
正在运行的方法 会有一个方法栈
方法的重载:overload 方法名相同 形参列表不同 和方法的返回值没有关系
形参列表不同指的是: 形参的个数 类型 顺序
JDK1.5 出现的新特性:
1. foreach
2.不定长参数
方法名(类型...变量名){
}
不定长的参数 其实就是一个数组
注意:
1.格式: 数据类型...变量名
2.最后一个参数才能使用不定长参数的形式
3.不定长参数 可以接受多个参数 也可以接受数组 也可以不传入值
属性(变量):
变量: 全局变量 局部变量
全局变量(成员变量): 写在类中的变量
如果不赋值,系统会自动赋初值0
局部变量: 方法中的 方法参数列表中的 代码块中
当局部变量和全局变量相同时,局部覆盖全局
如果不赋值 不用不报错一用就报错 系统是不会为局部变量赋初值的
构造方法:
格式: 修饰符 方法名(和类名是相同的){}
不允许程序员自己调用 是JVM虚拟机调用的
问:什么时候调用构造方法?
答: 当对象被创建的时候
问:为什么不写返回值?
答:底层默认返回的是当前类的对象 所以默认不加返回值
不写构造方法的时候 系统会默认得添加一个
static: 关键字
static 可以修饰 属性 方法 内部类 代码块
被static修饰的东西 代表属于类的
不被static修饰的 代表属于对象的
被static修饰的不可以调用非static修饰的
非static修饰的 可以调用static修饰的
单例模式:
单例: 只有一个实例对象
要求在整个应用中只存在一个当前类的对象
懒汉式 饿汉式
1.构造方法私有化 private
2.提供一个静态的私有的变量引用自己
3.提供一个static的返回当前类的那个变量的方法
修饰符的作用:
public:所有的类中都有效
protected:当前包中的类和其他包中的所有子类有效
default(不写):只有当前包中的类有效
private:只有当前类中有效
两种模式的代码:
/** * 饿汉式 */ public class Person { /** * 构造方法私有化 */ private Person(){//表示在其他类中不能创建这个类的实例了 } /** * 提供一个静态的私有的变量来引用自己 */ private static Person person=new Person(); /** * 提供一个静态的返回当前类的变量的方法 */ public static Person getInstance(){ return person; }
/** *懒汉式 * */ public class Student { /** * 构造方法私有化 */ private Student(){//表示在其他类中不能创建这个类的实例了 } /** * 提供一个静态的私有的变量来引用自己 */ private static Student student=null; /** * 提供一个静态的返回当前类的变量的方法 */ public static synchronized Student getInstance(){//这个锁是防止两个对象同时被实例化出来 if(student==null){ student=new Student(); } return student; }
java中面向对象的三大特性: 封装 继承 多态
封装与隐藏
1.修饰符体现 使用private进行封装
2.包体现 :package
倒域名规则
www.baidu.com
com.baidu.www
com/cn.公司名.项目名.模块名
com.guigu.studentmanager.dao
com.guigu.studentmanager.service
作用:
1.划分模块
2.解决类名冲突 在一个包中不允许出现相同名字的类
JavaBean model entity实体 pojo领域对象 这些都是一个意思
JavaBean是一种特定的类
全局变量私有化,提供set和get方法
目前有两种模型:
1.贫血模型 领域对象中没有其他方法,只有属性和set和get
2.充血模型 领域对象中除了属性、set和get外还有他自身的方法
继承:
子类只能继承父类的非private 属性及方法
java中的继承是单继承的!
注意:
1.子类被实例化时父类先被实例化,然后是子类实例化
2.java中所有的类的父类是object类 extends Object
3.子类的方法如果和父类的方法重名,子类的方法会覆盖父类的方法这叫
做方法的覆盖 override
4.想要调用父类的方法使用关键字 super
java的内置对象:
this:代表的是类的对象
super:代表的是当前父类的对象
类中的执行顺序 先静态代码块 后非静态代码块 再构造方法 子类被实例化时父类先被实例化,然后是子类实例化
代码证明:
public class Father { static{ System.out.println("1"); } { System.out.println("2"); } public Father(){ System.out.println("3"); } public class Child extends Father{ static{ System.out.println("4"); } { System.out.println("5"); } public Child(){ System.out.println("6"); }
当创建了Child的对象后运行的结果为:1 4 2 3 5 6
在看类的实例化和初始化的时候看到的很好的例子:
class T implements Cloneable{ public static int k = 0; public static T t1 = new T("t1"); public static T t2 = new T("t2"); public static int i = print("i"); public static int n = 99; public int j = print("j"); { print("构造快"); } static { print("静态块"); } public T(String str) { System.out.println((++k) + ":" + str + " i=" + i + " n=" + n); ++n; ++ i; } public static int print(String str){ System.out.println((++k) +":" + str + " i=" + i + " n=" + n); ++n; return ++ i; } public static void main(String[] args){ T t = new T("init"); } }
输出的结果:
1:j i=0 n=0 2:构造快 i=1 n=1 3:t1 i=2 n=2 4:j i=3 n=3 5:构造快 i=4 n=4 6:t2 i=5 n=5 7:i i=6 n=6 8:静态块 i=7 n=99 9:j i=8 n=100 10:构造快 i=9 n=101 11:init i=10 n=102
这里面清楚得描述了类在实例化的时候各个代码执行的顺序。