目录
Java面向对象
含义
面向对象:稳定性、可拓展性、可重用性。
面向对象的三大特征:封装、多态、继承。
类和对象
类:确定对象将会拥有的特征(属性)和行为(方法),即虚拟化的模版(动物)
对象:是类的实例化表现(猫、狗、鸡)
类是对象的类型,对象是特定类型的数据
属性和方法
属性:对象具有的各种静态特征,即“对象有什么”
方法:对象具有的各种动态行为,即“对象能做什么”
类的创建
public class CatDemo{
//成员属性:昵称、年龄、体重
String name;
int month;
double weight;
//成员方法:跑、吃
public void run(String name) {
System.out.println(name+"跑啦!");
}
//吃东西的方法
public void eat(String name) {
System.out.println(name+"吃饭!");
}
}
实例化对象
public class CatTest{
public static void main(String[] args) {
// 对象实例化
CatDemo one=new CatDemo();
//测试
one.name="喵喵";
one.month=2;
one.weight=5;
System.out.println("昵称:"+one.name);
System.out.println("年龄:"+one.month);
System.out.println("体重:"+one.weight);
one.run(one.name);
one.eat(one.name);
}
}
注意:
实例化对象的过程:1、申明对象,2、实例化对象
需要多次访问同一对象时,必须进行声明。
同一作用范围内,不能定义同名对象。
java内存管理
栈:每个方法在执行时,都会创建一个栈帧。栈中所存储,多用于保存局部信息,如:方法体中的基本数据类型定义的变量、对应的引用等。当局部作用范围结束时,栈内信息立即自动释放。当存储内容为基本数据类型,声明局部变量时,存储的是他们对应的具体数值。当存储的是局部对象的引用时,存储的是具体对象在堆中的地址。
堆:用来存放动态产生的数据,如new出来的对象。创建出来对象只包含成员变量,并不包括成员方法。当对象使用结束,并确定无实例引用只想堆空间时,JVM才会依据相关垃圾回收机制进行资源回收,完成堆内资源释放。
构造方法
格式
public 构造方法名(//可带参){
//可初始化代码
}
注意:
1.构造方法与类同名且没有返回值
2.只能在对象实例化的时候调用
3.一个类中可以有多个构造方法
4.当没有指定构造方法时,系统会自动添加无参的构造方法
5.当有指定构造方法,无论是有参、无参的构造方法,都不会自动添加无参的构造方法.
6.构造方法在类外调用必须也只能配合new来调用Cat one=new Cat(, , );不能通过对象名来调用。
7.构造方法不能在类成员方法中被调用,构造方法的调用只能在构造方法之间来调用。同一个类的构造方法可以通过this();调用。并且this()必须放在方法体内第一行,如果构造方法中有参数,只需要把参数放进this()中,即this(参数)。不能在类中普通成员方法内通过this调用构造方法。
8.进行构造方法的调试时,如果希望进入构造方法内部,需要在对应的构造方法上一行设置断点,否则会进入Class类文件中。
debug进入之后单步执行直接报错sourcenotfound解决:
source不是报错,由于没有配置原码信息,再加上断点设置的位置关系,才会展示该界面。
配置原码信息:Edit Source-External location-ExternalFile-路径为安装javaJDK的路径,在此路径下找到src.zip-ok便可看到类文件代码。
this关键字
1.代表当前对象本身,可以理解为指向当前对象的引用
2.this在Java中可以用于调用成员属性、成员方法、构造方法,也可以当作参数进行方法传参以及方法返回值。
Java封装
概念特点
封装:只留出使用方法给外部调用,外部不需要知道封装类里面的代码实现,只能看到这个封装类具体能用来做什么(ATM机)。
封装将类的某些信息隐藏在类内部,不允许外部程序直接访问
通过该类提供的方法来实现对隐藏信息的操作和访问
隐藏对象的信息,同时留出访问的接口
特点:只能通过规定的方法访问数据;隐藏类的实例细节,方便修改和实现。
实现
封装代码:
1、对类里面需要设置不能对外直接访问的属性 设置private 私有属性:只能在当前类内访问,外部无法访问
2、设置set,get方法,当需要改变类里面属性可以通过set方法来设置属性值,通过get方法来获取属性值
3、在set/get方法中加入属性控制语句,可以在这里对传入的值进行验证,验证通过才能赋值给属性。
例子
图书信息
public class Book {
//私有属性:书名、作者、出版社、价格
private String name;
private String author;
private String publicc;
private double price;
//通过构造方法实现属性赋值
public String getName(){
return name;
}
public String getAuthor(){
return author;
}
public double getPrice(){
return price;
}
public String getPublicc(){
return publicc;
}
public void setName(String name){
this.name=name;
}
public void setAuthor(String author){
this.author=author;
}
public void setPublicc(String publicc){
this.publicc=publicc;
}
public void setprice(double price){
this.price=price;
}
public Book(String name,String author,String publicc,double price){
this.name=name;
this.author=author;
this.publicc=publicc;
this.price=price;
}
}
public class BookTest {
public static void main(String[] args) {
//实例化对象
Book one=new Book("数据结构","ab","科学出版社",30.0);
Book two=new Book("操作系统","cd","清华出版社",46.5);
System.out.println("书名:"+one.getName());
System.out.println("作者:"+one.getAuthor());
System.out.println("出版社:"+one.getPublicc());
System.out.println("价格:"+one.getPrice()+"元");
System.out.println("===================");
System.out.println("书名:"+two.getName());
System.out.println("作者:"+two.getAuthor());
System.out.println("出版社:"+two.getPublicc());
System.out.println("价格:"+two.getPrice()+"元");
}
}
包的类管理
定义包
同一个包中,类不许重名,不同包下,类可以重名:
-
java中一个包里不能存在同名类
-
包的命名:域名倒序+模块+功能
-
域名全部小写
-
package 包名代码必须放在Java源文件中的第一行
-
建议每个包内存储信息功能单一
导入包
当需要引入本包之外定义的类时,可以通过import语句进入信息导入,以简化代码编写
语法格式:import 包名.类名;
注意:
package 必须放在Java源文件中的第一行,一个Java源文件中只能有一个package语句。如缺省,则指定为无名包。
一个Java源文件中可以有多条import。如缺省,则默认导入java.lang包下的全部类。
import需要写在class语句上面,即一个java文件的存在顺序应是:package-import-class
1、采用“import 包名.类名;”的方式加载
2、加载顺序跟import导入语句位置无关
3、“import 包名.*”只能访问指定包名下面的类,无法访问子包的类
import 包名.类:导入指定包名下的指定类
4、加载不同包下的同名类,以导入的必须使用全名。如果都导入全部类,则会报错(分不清)。当分别以*和指定类名进行导入时,以类名导入优先级更高。
static关键字
1.static+成员变量
被static修饰的成员为静态成员/类成员,无论有多少个实例,都共用一个静态空间;
静态成员属于整个类,由类进行维护,仅在类初次加载时会被初始化,在类销毁时回收;而非静态成员属于对象独有,每个对象进行实例化时产生各自的成员,随着对象的回收而释放。
静态成员在类加载期间就已经完成初始化,优先于对象而存在,可以通过类名、对象名两种方式访问;而非静态成员只能通过对象名访问。
2.static+成员方法
静态方法中可以通过“类名.成员“或”成员”的方式访问类内静态成员/静态方法。
不允许直接访问本类中的非静态成员/非静态方法。
可以通过实例化产生本类对象,通过“对象.成员“的方式访问类内非静态成员/非静态方法。
3、static+代码块
静态代码块:被static修饰的,定义在类的内部,用{}括起来的代码段。
构造代码块:没有被static修饰的,定义在类内部,用{}括起来的代码段
普通代码块:定义在方法内部,用{}括起来的代码段。
静态代码块:
只能出现在类内,不允许处在方法内。
可以出现多次,按顺序在类加载时执行
无论类实例化多少对象,只执行一次。
构造代码块:
可以在类内出现多次,按顺序在每个对象实例化时执行
执行优先级:晚于静态代码块,高于构造方法
每次执行对象实例化时,均会执行一次。
普通代码块:
可以在方法内出现多次,按顺序在方法用时执行.
注意:
1.静态代码块无论实例化多少个对象,都只执行一次;而构造代码块在每一次实例化对象时都会执行一次,即实例化多少个对象就执行多少次。
2.在静态代码中,只能直接给静态成员赋值,如果要调用非静态成员,需要先实例化对象,然后用对象名.成员的方式调用。
3.不能在静态代码块声明静态成员,可以声明局部变量;静态代码块中声明的变量,在外部无法进行访问。
4.方法内定义的局部变量,作用范围为:自定义位置起,至其所在的代码块结束,在相同范围内,不允许定义相同名称的变量。
例子
运行优先顺序
class Code{
//Code类的构造块
{
System.out.println("Code的构造块");
}
//Code类的静态代码块
static{
System.out.println("Code的静态代码块");
}
//Code类的构造方法
public Code(){
System.out.println("Code的构造方法");
}
}
public class Codes{
// Codes的构造块
{
System.out.println("Codes的构造块");
}
//Codes的静态代码块
static{
System.out.println("Codes的静态代码块");
}
//Codes的构造方法
public Codes(){
System.out.println("Codes的构造方法");
}
public static void main(String[] args){
System.out.println("Codes的主方法");
System.out.println("产生COde类实例化对象");
Code one =new Code();
System.out.println("产生Codes类实例化对象");
Codes two=new Codes();
}
}
运行结果:
Codes的静态代码块
Codes的主方法
产生COde类实例化对象
Code的静态代码块
Code的构造块
Code的构造方法
产生Codes类实例化对象
Codes的构造块
Codes的构造方法
分析:类加载是便执行静态代码块-输出--Codes的静态代码块;接着System.out.println(--)输出--Codes的主方法、产生COde类实例化对象;接着加载Code类输出--Code的静态代码块;然后构造代码块在类的实例化时执行,输出--Code的构造块,然后输出构造方法--Code的构造方法;后面Codes类同理。