Java笔记--03

来源:互联网 发布:手机快速充电软件 编辑:程序博客网 时间:2024/05/19 01:11

面向过程与面向对象的区别?(盖饭、蛋炒饭)
采用面向过程必须了解整个过程,每个步骤都有因果关系,每个因果关系都构成了一个步骤,多个步骤就构成了一个系统,因为存在因果关系每个步骤很难分离,非常紧密,当任何一个步骤出现问题,将会影响到所有的系统。高耦合:代码和代码之间的联系程度高。
面向对象会将现实世界分割成不同的单元(对象),实现各个对象,如果完成某个功能,只需要将各个对象协作起来就可以。
面向对象的三大特征
封装
继承
多态
类和对象的概念
类是对具有共性事物的抽象描述,是在概念上的一个定义
通常根据名词(概念)来发现类,如在成绩管理系统中,学生、班级、课程、成绩
学生-张三
班级-315
课程-软件工程
成绩-张三成绩
以上”张三”,”315”,”软件工程”,”张三成绩”他们是具体存在的,称为对象,也叫实例
也就是说一个类的具体化,就是对象或实例。
为什么面向对象成为主流技术?
主要是因为面向对象更符合人的思维模式,更容易分析现实世界
从软件的开发生命周期来看,基于面向对象可以分为三个阶段
OOA(面向对象的分析)
OOD(面向对象的设计)
OOP(面向对象的编程)–Java就是一个纯面向对象的语言
类=属性+方法
类是一种引用数据类型
属性来自于类的状态,而方法来自于类的动作
类的定义
类的修饰符 class 类名 extends 父类名 interface 接口名{ 类体:属性和方法组成}
定义在类体中的变量分为两种:
如果没有static修饰就是成员变量也叫实例变量或非静态变量,该变量是对象级别的,必须先有对象才能访问,不能使用类直接访问,成员变量在堆中的对象中存储,成员变量如果没有手动赋值,系统则默认赋值
系统默认
基本数据类型:
byte、short、int、long 0
float、double 0.0
char \u0000
boolean false
引用数据类型 null
成员变量只属于当前的对象(只属于对象,不属于类),只有通过对象才可以访问成员变量(访问方式”引用.成员变量”),通过类不能直接访问成员变量
如果有static修饰就是类变量或静态变量,该变量可以使用类直接访问
Java中所有new出来的数据统一被存储在堆区中,程序员无法对堆区数据直接操作,只能通过内存地址间接操作。
定义在方法中的变量是局部变量(包括方法参数列表)
局部变量在栈中存储
Student stu1=new Student();
stu1是一个局部变量(不是对象),这个变量是Student类型,也就是一个引用类型,stu1称作”引用
stu1该局部变量称作引用,引用中保存的是对象在堆中的内存地址,通过”引用”去间接访问堆中的对象
面向对象的封装性
1.属性私有化
2.对外提供公开的set和get方法
关于Java的构造函数
1.构造方法语法:
[修饰符列表] 构造方法名(形式参数列表){
方法体;
}
2.构造方法的方法名必须和类名一致
3.构造方法的作用是什么?
第一、创建对象
第二、给成员变量赋值(也就是初始化成员变量)
4.构造方法应该如何调用?
new 构造方法名(实参);在堆中开辟空间存储对象
5.如果一个类没有提供任何构造方法,系统默认提供无参数构造方法
如果一个类已经手动的提供了构造方法,那么系统不会再提供任何构造方法。
6.成员变量到底什么时候赋值?
只有在调用构造方法的时候,才会给成员变量赋值
构造方法主要用来创建类的实例化对象,可以完成创建实例化对象的初始化工作,
声明格式: 构造方法修饰词列表 类名(方法参数列表)
构造方法修饰词列表:public、proteced、private
类的构造方法和普通方法一样可以进行重载
构造方法具有的特点:
1. 构造方法名称必须与类名一致
2. 构造方法不具有任何返回值类型,即没有返回值,关键字 void 也不能加入,
加入后就不是构造方法了,就成了普通的方法了
3. 任何类都有构造方法,如果没有显示的定义,则系统会为该类定义一个默认的构造器,
这个构造器不含任何参数,如果显示的定义了构造器,系统就不会创建默认的 、不含参数的构造器了。


Java内存划分
Java虚拟机管理的内存分为三大块
栈区、堆区和方法区
其中,
方法区:用来存储类的所有信息,包括所有的方法,静态变量,常量
栈区:每调用一个方法,会创建一个栈帧,存放局部变量
堆区:存放new出来的对象,此对象由垃圾收集器收集,垃圾收集器针对的就是堆区

什么时候垃圾回收器会回收垃圾?
如果堆中的对象没有更多的引用指向它,则该对象变成了垃圾,等待垃圾回收器的回收。
当不使用new关键字时,出现的问题?
Student s=new Student();
s=null;//赋值覆盖new Student();使局部变量s不指向任何对象
System.out.println(s.name);//编译不报错,运行报空指针异常
参数传递
只要是基本类型,传递过去的都是值
除了基本类型外都是址传递
this关键字
1.this是什么?
this是一个引用类型,在堆中的每一个java对象上都有this,this保存内存地址指向自身
2.this能用在哪些地方?
第一、this可以用在成员方法中
this用在成员方法中,谁去调用这个成员方法,this就代表谁,this指的就是当前对象。
第二、this可以用在构造方法中
语法:this(实参);//用来在构造方法中调用另一个构造方法且这个语句只能放在构造方法中的第一句
目的:代码重用
this不能用在静态方法中
静态方法的执行根本不需要java对象的存在,直接使用类名. 的方式调用
而this代表的是当前对象,所以静态方法中根本没有this
this可以用来区分成员变量和局部变量
static关键词
1.static修饰的变量叫做”静态变量”
2.static修饰的方法叫做”静态方法”
3.static还可以定义静态语句块
静态语句块和实例语句块
static修饰的语句块叫静态语句块,静态语句块在类加载阶段执行,且只执行一次,并且是自上而下的顺序执行
没有static修饰的语句块叫实例语句块,每一次调用构造方法之前会执行一次,实例语句块执行顺序也是自上而下。
静态方法
一般情况下工具类中的方法大部分都是静态方法
静态方法不创建对象也能直接访问该方法
可以使用”类名.”方式调用
静态方法中不能直接访问非静态数据
静态方法中不能使用this
静态方法按照正规的方式访问:”类名.”
静态方法也能用”引用.” 方式访问,实质:编译阶段检查出引用是static类型,编译通过,
运行的时候,仍然使用”类名.”的方式访问
StaticTest s=null;//StaticTest是类名
s.m1();//m1方法是静态方法,这样的话运行也不报空指针异常//静态方法执行不需要对象,即使用引用底层用的也是”类名.”
变量详解
变量分类;
1.局部变量 在栈中存储
2.成员变量(实例变量、非静态变量) 在堆中的对象中存储,在创建对象的时候初始化
3.静态变量 在方法区中存储,所有java对象共享这一份,所以静态变量是类级别的,使用”类名.”方式访问,在类加载阶段赋值,并且只赋值一次
什么时候声明成静态变量?
如果这个属性所有的对象都有,并且这个属性的值是相同的,则该属性声明成静态的。
关于代码的顺序
public class Test{
//编译通过
static int i=10;
static {
System.out.println(i);
}
}
public class Test{
//报非法向前引用异常
static {
System.out.println(i);
}
static int i=10;
}
类中都可以有什么?
类{
//可以通过”类名.”访问,也可以通过”引用.”访问,底层也是”类名.”方式访问
//1.静态变量
//2.静态方法

    //必须对象存在才可以访问,采用"引用."    //3.成员变量    //4.成员方法    //创建对象,给成员变量赋值    //5.构造方法    //类加载时执行且只执行一次    //6.静态语句块    //构造方法每次调用之前执行    //7.实例语句块    //用在成员方法和构造方法中    //8.this  }

空指针异常:空引用访问成员抛空指针异常,空引用访问静态不抛异常
java类的继承
继承的基本作用:代码的重用
继承最重要的作用:方法可以重写
java语言中子类继承父类,会将父类中所有的数据全部继承,包括私有的也能继承过来,
但是在子类中无法直接访问父类中的私有的数据,但是可以间接访问
注意:构造方法无法被子类继承
关于方法覆盖
什么时候要进行重写?
如果父类中的方法已经无法满足当前子类的业务需求,需要将父类中的方法进行重写一遍
2.子类如果重写父类中的方法,则子类对象调用的一定是重写之后的方法
3.发生方法覆盖的条件?
第一、发生在具有继承关系的两个类之间
第二、必须具有相同的方法名,相同的返回值类型,相同的参数列表
第三、重写的方法不能比被重写的方法拥有更低的访问权限
第四、重写的方法不能比被重写的方法抛出更宽泛的异常
第五、私有的方法不能被覆盖
第六、构造方法无法被覆盖,因为构造方法无法被继承
第七、静态的方法不存在覆盖,因为静态方法执行和对象无关
第八、覆盖指的是成员方法,和成员变量无关
关于java语言中向上转型和向下转型
1.向上转型(upcasting):子–>父
2.向下转型(downcasting):父–>子
注意:无论是向上转型还是向下转型,两个类之间必须要有继承关系
向上转型又被称作:强制类型转换
父类型的引用指向子类型对象
程序分两个阶段:编译阶段,运行阶段
Animal a1 = new Cat();//Cat继承了Animal类
程序在编译阶段只知道a1是一个Animal类型,程序在运行的时候堆中的实际对象是Cat类型
a1.eat();//Animal和Cat中都有eat();方法
程序在编译阶段a1被编译器看做Animal类型
所以程序在编译阶段a1引用绑定的是Animal类中的eat方法(静态绑定)
程序在运行的时候堆中的对象实际是Cat类型,而Cat已经重写了eat方法
所以程序在运行阶段对象的绑定的方法是Cat中的eat方法(动态绑定)
向下转型:强制类型转换
Animal a1=new Cat();//向上转型又被称作:强制类型转换
要执行Cat类中的move方法,而该方法在Animal类中没有,该怎么做?
只能强制类型转换,需要加强制类型转换符
Cat c1=(Cat)a1;
判断以下程序运行的时候会出现什么问题?
Animal a2 = new Dog();//Dog继承了Animal
Cat c2 = (Cat)a2;//java.lang.ClassCastException
在做强制类型转换的时候程序是存在风险的!!
为了避免java.lang.ClassCastException的发生,java引入了instanceof运算符
用法:
1.instanceof运算符的运算结果是boolean类型
2.(引用 instanceof 类型)–>true/false
例如:(a instanceof Cat)如果结果是true,表示a引用指向堆中的java对象是Cat类型
推荐:在做向下转型的时候要使用instanceof运算符判断,避免ClassCastException
多态的好处?
1.使用多态可以使代码之间的耦合度降低
2.项目的扩展能力强
推荐:编程的时候不要面向具体编程,要面向父类型编程,面向抽象编程
super关键字
1.super不是引用类型,super中存储的不是内存地址,super指向的不是父类对象
2.super代表的是当前子类对象中的父类型特征
3.什么时候使用super?
子类和父类都有某个数据,例如,子类和父类中都有name这个属性
如果要在子类中访问父类中的name属性,需要使用 super.
4.super可以用在什么什么地方?
第一、super可以用在成员方法中,不能用在静态方法中
第二、super可以用在构造方法中
super关键字用在构造方法中
语法:super(实参);
作用:通过子类的构造方法去调用父类的构造方法
语法规则:一个构造方法第一行如果没有this(…);也没有显示的去调用super(…);
系统会默认调用super();
注意:super(…)的调用只能放在构造方法的第一行
super(…)和this(…)不能共存
super(…);调用了父类的构造方法,但是并不会创建父类对象
通过子类的构造方法去调用父类的构造方法,作用是:给当前子类对象中的父类型特征赋值
在java语言中只要是创建java对象,那么Object中的无参构造方法一定会执行

注意:单例模式的类型没有子类,无法被继承,因为子类继承父类会默认调用父类中的无参构造方法并且单例模式中的构造方法私有化了,不能被子类调用
finfal关键字
1.final修饰的类无法被继承
2.final修饰的方法无法被覆盖
3.final修饰的局部变量,一旦赋值,不可改变
4.final修饰的成员变量必须显示的初始化即必须手动初始化
final修饰的成员变量一般和static连用
常量:值不可再改变的变量
java规范中要求所有的常量变量名要大写
5.final修饰的引用类型,该引用类型不可再重新指向其他的java对象
6.final不能修饰抽象类,也不能修饰抽象方法,因为抽象类要被继承,抽象方法要被重写
抽象类
1.如何定义抽象类?
class关键字前加abstract
2.抽象类无法被实例化
3.虽然抽象类无法实例化,但是抽象类也有构造方法,该构造方法是给子类创建对象用的
4.抽象类中可以定义抽象方法
抽象方法的语法:在方法的修饰符列表中添加abstract关键字,且抽象方法应该以”;”结束,不能带有”{}”
例如:public abstract void m1();
5.抽象类中不一定有抽象方法,但抽象方法必须出现在抽象类中
6.一个非抽象的类继承抽象类,必须将抽象类中的抽象方法覆盖,实现,重写
接口
接口也是一种引用类型,可以等同看做类
1.如何定义接口,语法:
[修饰符] interface 接口名{}
2.接口中只能出现:常量、抽象方法
3.接口其实就是一个特殊的抽象类,特殊在接口是完全抽象的
4.接口中没有构造方法,无法被实例化
5.接口和接口之间可以多继承
6.一个类可以实现多个接口(这里的”实现”可以等同看做”继承”)
7.一个非抽象的类实现接口,需要将接口中所有的方法”实现/重写/覆盖”
public interface A{
//常量必须用public static final修饰
public static final double PI=3.14;
//public static final是可以省略的
byte MAX_VALUE=127;
//接口中所有的抽象方法都是public abstract
public abstract void m1();
//public abstract是可以省略的
void m2();
}
8.实现接口用implements关键字,implements和extends意义相同
如果要实现多个接口,在接口之间加”,”
例如:class D implements A,B,C{重写接口A,B,C中的方法}
9.接口和抽象类都能完成某个功能,优先选择接口
因为接口可以多实现,多继承,并且一个类除了实现接口之外,还可以去继承其他类(保留了类的继承)
接口的作用:
1.可以使项目分层,所有层都面向接口开发开发效率提高了
2.接口使代码和代码之间的耦合度降低,就像内存条和主板的关系,变得”可插拔”,可以随意切换
关于Object中的toString方法
SUN在Object类中设计toString方法的目的:返回java对象的字符串表示形式
在显示的开发过程中,Object里边的toSting方法已经不够用了
因为Object的toString方法的实现结果不满意
Object中的toString方法就是要被重写的
SUN是这样实现toString方法的
public String toString(){
return getClass().getName()+”@”+Integer.toHexString(hasCode);
}
Object中的toString方法返回:类名@Java对象的内存地址经过哈希算法得出的int类型再转换成十六进制
这个输出结果可以等同看做java对象在堆中的内存地址
print和println方法后面的括号中如果是一个引用类型,会默认调用引用类型的toString方法
关于Object中的equals方法
java对象中的equals方法的设计目的:判断两个对象是否一样
Object中的equals方法比较的是两个引用的内存地址
在现实的业务逻辑中,不应当比较内存地址,应该比较内容
所以Object中的equals方法也要重写,要根据需求规定重写equals方法
==两边如果是引用类型,则比较的内存地址,地址相同为true,否则false
关于java语言中如何比较两个字符串是否一致
在java中比较两个字符串是否一致,不能用”==”
只能调用String类的equals方法(String已经重写了Object中的equals方法,比较的是内容)
关于Object中的finalize方法
finalize方法什么时候调用?
1.finalize方法每个java对象都有
2.finalize方法不需要程序员去调用,由系统自动调用
3.java对象如果没有更多的引用指向它,则该Java对象成为垃圾数据,
等待垃圾回收器的回收,垃圾回收器在回收这个java对象之前会自动调用该对象的finalize方法
finalize方法是该对象马上就要被回收了,例如,需要释放资源,则可以在该方法中释放
程序员只能”建议”垃圾回收器回收垃圾
System.gc();
要想执行finalize方法有效果,就要重写finalize方法
而且就算执行finalize方法也不一定回收垃圾,
因为可以在finalize方法中挽救该对象,即把该引用重新赋值给该对象
关于Object中的hasCode方法
hasCode方法返回的是该对象的哈希码值
java对象的内存地址经过哈希算法得出的int类型的数值
关于package和import
包机制:
1.为了解决类的命名冲突问题,在类名前加命名空间(包机制)
2.在java中使用package语句定义包
3.package语句只能出现在.java源文件的第一行
4.package定义的格式,通常采用公司域名倒叙方式
package定义的全格式:公司域名倒叙.项目名.模块名;
5.完整的类名是带有包名的
6.带有package语句的java源文件必须这样编译:
javac -d 生成路径 java源文件路径
7.运行:
java 全类名 //带包名
import语句可以引入其他类
import语句只能出现在package语句之下,class定义的语句之上
语法:
import 全类名;
java.lang;软件包下所有类不需要手动导入,系统自动导入
关于访问控制权限修饰符
private 只能在本类中访问
缺省 本类,同一个包下可以访问,不同包下不行
protected 本类,同一个包下可以访问,不同包下不行,但是可以在子类中访问
public 可以在任何位置访问
因此,类只能用public或者缺省方式
关于内部类
内部类分为:静态内部类、成员内部类、局部内部类、匿名内部类
内部类的重要作用:可以访问外部类的私有数据
静态内部类:
1.静态内部类可以等同看做静态变量
2.静态内部类可以直接访问外部类的静态数据,无法直接访问成员
3.静态内部类可以用访问控制权限的修饰符修饰(所有的都能用)
4.创建静态内部类对象的方式:外部类名.内部类名 引用 = new 外部类名.内部类名();
成员内部类:
1.成员内部类可以等同看做成员变量
2.成员内部类可以访问外部类所有的数据
3.静态内部类可以用访问控制权限的修饰符修饰(所有的都能用)
4.创建成员内部类对象的方式:外部类名.内部类名 引用 = new 外部类名().new 内部类名();
5.成员内部类中不能有静态声明
局部内部类:
1.局部内部类可以等同看做局部变量
2.局部内部类可以访问外部类所有的数据
3.局部内部类不能用访问控制权限的修饰符修饰
4.局部内部类中数据的调用必须在该类所在的方法中调用
5.局部内部类中不能有静态声明
6.局部内部类在访问局部变量的时候,局部变量必须使用final修饰
匿名内部类:
1.匿名内部类指的是没有名字的局部内部类
2.匿名内部类的格式:
new 接口名(){需要实现的方法}
3.匿名内部类可以直接访问外部类的静态数据,无法直接访问成员
4.匿名内部类中不能有静态声明
类和类之间的关系
1、泛化关系:类和类之间的继承关系及接口与接口之间的继承关系
2、实现关系:类对接口的实现
3、关联关系:类与类之间的连接,一个类可以知道另一个类的属性和方法,即在当前类中含有其他类的引用,在java语言中使用成员变量体现

class Me{    String name;    Friend f;//Friend是另一个类,则MeFriend就是关联关系    }

4.聚合关系:是关联关系的一种,是较强的关联关系,是整体和部分的关系,如:汽车和 轮胎,它与关联关系不同,关联关系的类处在同一个层次上,而聚合关系的类处在不平等的层次上,一个代表整体,一个代表部分,在java 语言中使用实例变量体现

public class  ClassRoom { //ClassRoom和List属于关联关系,在同一个层次上    List<Student> stu;//ClassRoom和Student是聚合关系,一个是整体,一个是部分    }    public class  Student {          }

5.合成关系:是关系的一种,比聚合关系强的关联关系,如:人和四肢,整体对象决定部分对象的生命周期,部分对象每一时刻只与一个对象发生合成关系,在 java 语言中使用实例变量体现

public class  Person { //Person和List属于关联关系,在同一个层次上    List<Body> b;//Person和Body是合成关系,person是整体,body是部分,整体和部分紧密相连    }    public class  Body {          }

6.依赖关系:依赖关系是比关联关系弱的关系,在 java 语言中体现为返回值,参数,局部变量和静态方法调用

public class Test{    public void m1(){    //局部变量    User u=new User();//依赖关系    }    }    class User{}

is a,is like a,has a
is a:继承关系,如Dog is a Animal
is like a:实现关系,如B is like a A,其中A是接口B是类
has a:关联关系,如A has a B,其中A和B都是类,且A类中有B类的引用

原创粉丝点击