1.面向对象的程序设计三个主要特性:封装性、继承性、多态性
- 封装性:把描述对象属性变量及实现对象功能的方法合在一起,定义为一个程序单位,并保证外界不能任意更改其内部的属性值,也不能任意调动其内部的功能方法。同时为封装在一个整体内的变量及方法规定了不同级别的访问权限。
- 继承性:增强了程序代码的可复用性,提高了软件开发效率,降低了程序产生错误的可能性,也为程序的修改提供了便利。
- 多态性:允许程序出现重名现象。包括方法重载、对象多态。方法重载:在一个类中,允许多个方法使用同一名字,但方法的参数不同,完成的功能也不同。对象多态:子类对象可以与父类对象进行相互的转换,而且根据其使用的子类的不同完成的功能也不同。多态性使得程序的抽象程度和便捷程度更高,有利于程序设计人员对程序的分组协同开发。
2. public static void fun()
加static关键字,与主方法定义在同一类中且由主方法直接调用。
public void fun()
不加static关键字,定义的方法由对象调用。
3.对象的创建
Person per = new Person();
类名 对象名称 = new 类名();
注意:对象使用前必须实例化,如果一个对象没有被实例化而直接使用,使用时会出现空指向异常。
4.引用传递的本质
不同的栈内存空间将指向同一块堆内存(一个栈内存只能够保存一个堆内存空间的地址),这样不同的栈内存将指向同一块堆内存,并且都可以对指向的堆内存空间数据进行修改。
类属于引用数据类型,进行引用传递时,传递的是堆内存的使用权。
class Person{
String name;
int age;
public void Info(){
System.out.println("name:"+name+", age:"+age);
}
}
public class Test {
public static void main(String args[]){
Person per1=new Person();
per1.age=10;
per1.name="kitty";
Person per2=per1;
per2.age=11;
per2.name="hello";
per1.Info();
per2.Info();
}
}
-------------------------------------------------------
name:hello, age:11
name:hello, age:11
5.类中全部属性必须进行封装,封装之后的属性必须通过setter,getter进行访问。
编写代码的时候最好采用this.方法的形式,容易查错。
6.构造方法
主要作用是为类中属性初始化
1)构造方法的名称必须与类名称一致
2)构造方法不能有任何返回值类型(void也不行)
public Person(String name,int age){//true
this.name=name;
this.age=age;
}
public void Person(String name,int age){//false
this.name=name;
this.age=age;
}
3)不能在构造方法中用return返回一个值
当调用关键字new实例化对象的时候才会调用构造方法
构造函数可以重载
public Person(){}
public Person(String name){}
public Person(String name, int age){}
7.匿名对象
new Person("lily",18).Info();
使用:匿名对象只在堆内存开辟空间,不存在栈内存的引用,该对象使用一次之后就等待被垃圾收集机制回收。
作用:在实际开发中一般作为其他类的实例化对象的参数传递的。
8.String类
实例化String类对象
String name1="lily";
String name2=new String("lily");
System.out.println("name1==name2:"+(name1==name2));
System.out.println("name1.equals(name2):"+name1.equals(name2));
---------------------------------------------------------------
name1==name2:false
name1.equals(name2):true
【问题】解释String类中“==”,equals()方法比较的区别
- “==”是Java提供的关系运算符,主要功能是进行数值相等判断,如果用在String对象上表示的是内存地址数值的比较;
- equals()方法是由String提供的一个方法,专门用于对字符串内容进行比较。
如果一个字符串已经被一个名称所引用,则以后再有相同的字符串声明时,不会再重新开辟空间。
【原理】String类所采用的设计模式为共享设计模式
当代码中使用了直接赋值的方法定义了一个String类对象时,会将此字符串对象所使用的匿名对象入池保存,如果后续还有其他String类对象也采用了直接赋值的方式且设置同样内容时,不会开辟新的堆内存空间,而是使用已有对象进行引用的分配,从而继续使用。
【问题】String类两种对象实例化方式的区别
- 直接赋值:只会开辟一块堆内存空间,并且会自动保存在对象池之中以供下次使用;
- 构造方法:会开辟两块堆内存空间,其中有一块空间将成为垃圾,并且不会自动入池,但用户可以通过intern()方法手工入池。
注意⚠️字符串内容一旦声明不能改变
String类中常用方法
9.引用传递
class Function{
int temp;
}
public class Test {
public static void main(String args[]){
Function fun=new Function();
fun.temp=50;
System.out.println("函数调用前temp:"+fun.temp);
Change(fun);
System.out.println("函数调用后temp:"+fun.temp);
}
public static void Change(Function f){
f.temp=100;
}
}
-----------------------------------------------------
函数调用前temp:50
函数调用后temp:100
public class Test {
public static void main(String args[]){
String str1="hello";
System.out.println("函数调用前temp:"+str1);
Change(str1);
System.out.println("函数调用后temp:"+str1);
}
public static void Change(String str){
str="world";
}
}
--------------------------------------------
函数调用前temp:hello
函数调用后temp:hello
class Function{
String temp;
}
public class Test {
public static void main(String args[]){
Function fun=new Function();
fun.temp="hello";
System.out.println("函数调用前temp:"+fun.temp);
Change(fun);
System.out.println("函数调用后temp:"+fun.temp);
}
public static void Change(Function f){
f.temp="world";
}
}
--------------------------------------------------
函数调用前temp:hello
函数调用后temp:world
【技术】简单Java类
包括:属性、构造方法、setter方法、getter方法
简单Java类的别名:POJO(plain ordinary Java object)、VO(value object)、PO(persistent object)、TO(transfer object)
10.this关键字
- 使用this调用本类属性——以后在类中访问属性的时候都要加上this关键字;
- 使用this调用构造方法——必须放在构造方法第一行
注意⚠️一般将无参构造方法作为出口,在无参构造方法中最好不要再调用其他构造方法
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(){
System.out.println("调用无参构造方法");
}
public Person(String name,int age){
this();
this.setAge(age);
this.setName(name);
}
}
public class Test {
public static void main(String args[]){
Person per=new Person("lily",18);
}
}
--------------------------------------------
调用无参构造方法
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(){
this("lily",18);
}
public Person(String name,int age){
System.out.println("调用有参构造方法");
this.setAge(age);
this.setName(name);
}
}
public class Test {
public static void main(String args[]){
Person per=new Person();
}
}
--------------------------------------------
调用有参构造方法
- this表示当前对象
11.static关键字
使用static声明属性
特点:
使用类名称访问static属性,不产生实例化对象也能调用
Person.country="ShangHai";
【Java中常用的内存区域】
- 栈内存空间——保存所有的对象名称(保存了引用的堆内存空间的地址)
- 堆内存空间——保存每个对象的具体属性内容
- 全局数据区——保存static类型的属性
- 全局代码区——保存所有的方法定义
使用static声明方法
特点:
- 可以直接由类名称在没有实例化对象的情况下进行调用;
- static方法只能调用static方法或static属性;
- static方法/属性都不是代码编写之初需要考虑的问题,只有在回避实例化对象且描述公共属性的情况下才考虑。有两种情况(1)本类没有提供有普通属性,这样产生实例化对象化对象无意义;(2)本类无法直接进行对象实例化,只能利用static操作。
理解main()方法
- public——表示此方法可以被外部调用
- static——表示此方法可以由类名称直接调用
- void——不需要返回值
- main——系统默认调用的方法名称
- String args[]——运行时的参数
如果一个方法要由主方法调用,必须声明时加上static,原因为,主方法是静态方法,而静态方法是不能调用非静态方法的。
12.代码块
- 普通代码块——直接在方法或语句中定义的代码块,进行程序分割使用;
- 构造块——直接写在类中的代码块,构造块优于构造方法执行,且每次实例化对象都会执行;
- 静态代码块——使用static声明的代码块,在类中定义的静态代码块优于构造块执行,不管有多少对象产生,静态代码块只执行一次;
- 动态代码块(多线程那里再补充)
class Demo{
{
System.out.println("1.构造块");
}
static{
System.out.println("0.静态代码块");
}
public Demo(){
System.out.println("2.构造方法");
}
}
public class Test {
public static void main(String args[]){
new Demo();
new Demo();
new Demo();
}
static{
System.out.println("在主方法所在类中定义静态块");
}
}
--------------------------------------------
在主方法所在类中定义静态块
0.静态代码块
1.构造块
2.构造方法
1.构造块
2.构造方法
1.构造块
2.构造方法
13.构造方法私有化
class Singleton{
private static Singleton instance=new Singleton();
public static Singleton getInstance() {
return instance;
}
private Singleton(){}
public void print(){
System.out.println("hello kitty");
}
}
public class Test {
public static void main(String args[]){
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
Singleton s3=Singleton.getInstance();
s1.print();
s2.print();
s3.print();
}
}
--------------------------------------------
hello kitty
hello kitty
hello kitty
单例设计模式:无论程序怎样运行,类永远只会有一个实例化对象存在。
只要将构造方法私有化了,就可以控制实例化对象的产生。
单态的应用:Windows中有一个回收站程序,除了桌面上的回收站外,每个硬盘都有一个回收站,实际上每个硬盘的回收站和桌面上的回收站是同一个,即整个操作系统上只有一个回收站实例,各个地方只是引用此实例。
14.内部类
class Outer{
private String info="hello kitty";
class inner{
public void print(){
System.out.println(info);
}
};
public void fun(){
new inner().print();
}
}
public class Test {
public static void main(String args[]){
new Outer().fun();
}
}
--------------------------------------------
hello kitty
使用内部类可以方便的访问外部类的私有操作。
在方法中声明的内部类要想访问方法的参数,则参数前必须加final,JDK1.8后此限制取消。
class Outer{
private String info="hello kitty";
public String getInfo(){
return this.info;
}
public void fun(){
new Inner(this).print();
}
};
class Inner{
private Outer out=null;
public Inner(Outer out){
this.out=out;
}
public void print(){
System.out.println(out.getInfo());
}
}
public class Test {
public static void main(String args[]){
new Outer().fun();
}
}
--------------------------------------------
hello kitty
用static声明的内部类变成外部类,不能访问非static的外部类属性