《Java开发实战经典》第五章 面向对象编程(基础篇)

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的外部类属性

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值