20210302Java面向对象

Java面向对象

编辑时间:2021/03/02

读完本节:大概花费40分钟,共4063词

1.方法参数的值传递机制(补充)
  1. 如下代码内存解析

    public class ValueTransferTest(){
        public static void main(String[] args){
        	
            String s1 = "hello";
            ValueTransferTest test = new ValueTransferTest();
            test.change(s1);
            
            System.out.println();//hello
    	}
    	public void change(String s){
            s = "world";
        }
    }
    

    image-20210302134434682

    image-20210302134449725

2.面向对象之封装与隐藏
  1. 程序设计的追求:高内聚、低耦合

    高内聚:类的内部数据操作细节,类自己完成,不允许外部干预

    低耦合:仅对外部暴露少量的方法用于使用

  2. 封装性的设计思想 :隐藏对象内部的复杂性,只对外部公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。

  3. 通过使用访问权限符来限定类内部数据xxx,通过setXxx()、getXxx()方法对数据进行操作,实现了对类的属性的封装。

    package Encapsulation;
    
    public class AnimalTest {
        public static void main(String[] args){
            Animal a = new Animal();
            //由于权限修饰符,无法直接访问name属性
            //a.name = "bobo";
            //'name' has private access in 'Encapsulation.Animal'
    
            //通过set方法对对象的属性进行赋值,通过get方法获取对象的属性
            a.setName("bobo");
            System.out.println("名字是:" + a.getName());
    
            /*
            通过对属性的封装,可以实现对用户的输入进行合法性判定
            在set方法内部可以设置对用户输入进行合法性判定*/
            //动物的legs无法是负数
            a.setLegs(-1);
            System.out.println(a.getLegs());
            a.setLegs(2);
            System.out.println(a.getLegs());
        }
    }
    class Animal{
        private String name;
        private int age;
        private int legs;
    
        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 int getLegs(){
            return legs;
        }
    
        public void setLegs(int legs){
            if(legs >= 0 && legs % 2 == 0){
                this.legs = legs;
            }else{
                System.out.println("输入有误");
                //在这里可以抛出异常
            }
    
    
        }
    }
    

    针对属性封装性的体现:

    当我们创建了一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里赋值操作要受到属性的数据和存储范围的制约。除此之外,没有其他的制约条件。但是在实际问题中,往往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加(比如setXxx()方法)。同时,我们需要避免用户再继续使用“对象.属性”的方式对属性赋值,因此需要将属性设置为“private”。在对属性添加了权限修饰符之后,用户无法对该属性进行直接访问,这样造成了功能的缺失,因此需要一个getXxx()方法来获取对象的属性值。

  4. 封装性的体现一:

    ​ 将类的属性xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx())和设置(setXxx())。

    封装性的体现二:

    ​ 不对外暴露私有的方法,对于某些类比如说快排当中,排序时需要对数据进行交换,这个时候用户无需知晓交换的进行,只需要给出待排数据即可,因此可以对快排中的交换方法进行私有化,不需要对外暴露。

    封装性的体现三:单例模式(将构造器私有化)

    封装性的体现四:如果不希望在包外被调用则将类的权限设置为缺省的

    封装性的体现还有很多…

3.权限修饰符
  1. Java规定的四种权限(权限从小到大):private、缺省(default)、protected、public

    用法:Java权限修饰符置于类的成员定义前,用来限定对象对该类成员的访问权限

    权限修饰符修饰成员的可见性

    修饰符类内部同一个包不同包的子类同一个工程
    privatetruefalsefalsefalses
    defaultturetruefalsefalse
    protectedtruetruetruefalse
    publictruetruetruetrue

    对于的权限修饰符之可以使用public和缺省(default),因为如果使用其他的权限修饰符,导致这个类无法被其他的类访问。

    public类可以在任意地方被访问;default类只能被同一个包的内部的类访问。

    image-20210302144612069

  2. 因为权限修饰符可以用于修饰类的成员,因此权限修饰符可以用来修饰类的内部结构:属性、方法、构造器、内部类

  3. 练习:

    创建程序,在其中定义两个类:Person和PersonTest类。定义如下:用setAge()设置人的合法年龄,用getAge()返回人的年龄。在PersonTest类中实例化Person类的对象p,调用setAge()和getAge()方法。

    image-20210302144955008

    package exer;
    
    public class Person {
        private int age;
    
        public void setAge(int age){
            if(age > 0 && age < 130){
                this.age = age;
            }else{
                //不在范围内抛出异常
                throw new RuntimeException("传入的数据非法");
            }
    
        }
        public int getAge(){
            return age;
        }
    }
    
    package exer;
    
    public class PersonTest {
        public static void main(String[] args){
            Person p = new Person();
    
            p.setAge(21);
            System.out.println(p.getAge());
            p.setAge(-1);
        }
    
    }
    

    image-20210302150134955

4.类的成员 - 构造器
  1. 构造器(constructor、构造方法)

    构造器的作用:①创建对象(new + constructor);②初始化对象的属性

    构造器的特征:①与类有相同的名称;②它声明返回值的类型(也不是声明为void);③不能被static、final、sychronized、abstract、native修饰,不能有return语句返回值。

  2. 1.如果没有显示定义类的构造器,JVM会提供一个默认的空参构造器;

    2.定义构造器的格式

    权限修饰符 类名(形参列表){}

    3.一个类中定义的多个构造器,彼此之间构成重载;

    4.一旦显示定义了类的构造器之后,JVM不再提供默认的空参构造器;

    5.一个类中,一定存在至少一个构造器,要么是默认空参构造器,要么是用户定义的构造器哦~

  3. 练习1.在Person类中添加构造器,利用构造器设置所有人的age属性初始值都为18

    ​ 2.在上述的类和构造器,增加name属性,使每次创建Person对象的同时初始化对象的age属性值和name属性值。

    //1
    package exer;
    
    public class Person {
        private int age;
    
        public Person(){
            age = 18;
        }
    
        public void setAge(int age){
            if(age > 0 && age < 130){
                this.age = age;
            }else{
                //不在范围内抛出异常
                throw new RuntimeException("传入的数据非法");
            }
    
        }
        public int getAge(){
            return age;
        }
    }
    
    ******************************
        
    package exer;
    
    public class PersonTest {
        public static void main(String[] args){
            Person p = new Person();
    
            System.out.println(p.getAge());
            p.setAge(21);
            System.out.println(p.getAge());
    //        p.setAge(-1);
        }
    
    }
    
    //2
    package exer;
    
    public class Person {
        private int age;
        private String name;
    
        public Person(){
            age = 18;
        }
        public Person(int age, String name){
            setAge(age);
            setName(name);
        }
    
        public void setAge(int age){
            if(age > 0 && age < 130){
                this.age = age;
            }else{
                //不在范围内抛出异常
                throw new RuntimeException("传入的数据非法");
            }
    
        }
        public int getAge(){
            return age;
        }
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
    }
    
    *************************
        
    package exer;
    
    public class PersonTest {
        public static void main(String[] args){
            Person p = new Person();
    
            System.out.println(p.getAge());
            p.setAge(21);
            System.out.println(p.getAge());
    //        p.setAge(-1);
    
            Person p1 = new Person(21, "bobo");
            System.out.println("name:" + p1.getName() + ", age: " + p1.getAge());
    
        }
    
    }
    

    image-20210302153415747

5.属性赋值过程
  1. 属性赋值的先后顺序

    赋值的位置:①默认初始化;②显示初始化;③构造器中初始化;④通过“对象.属性”或“对象.方法”的方式赋值

    赋值先后顺序:

    ① - ② - ③ - ④

    其中④可以重复多次的为同一个属性进行赋值

6.JavaBean和POJO
  1. JavaBean是一种Java语言写成的可重用组件,JavaBean的定义:

    类是公共的;

    有一个无参的构造器

    有属性,且有对应的get、set方法

  2. 用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象,用户可以认为JavaBean提供了一种随时随地的复制和粘贴的内容,而不用关心任何改变

  3. POJO(Plain Ordinary Java Object)是指普通Java类,具有一部分的get、set方法。

  4. JavaBean与POJO的关系:

    当一个Pojo可序列化,有一个无参的构造函数,使用getter和setter方法来访问属性时,他就是一个JavaBean。

7.UML类图

image-20210302161134356

8.this关键字
  1. this关键字的使用:this关键字可以用来修饰属性、方法、构造器

  2. this修饰属性和方法:此时this理解为”当前对象“或”正在创建的对象“

    1. 在类的方法中,可以通过使用”this.属性“或”this.方法“的方式,调用当前对象属性或方法。但是通常情况下都可以省略”this.“。特殊情况下,如果方法形参和类的属性同名时,就必须显示的使用”this.变量“的方式,表明此变量是属性,而非形参。
    2. 在类的构造器中,可以通过使用”this.属性“或”this.方法“的方式,调用当前对象属性或方法。但是通常情况下都可以省略”this.“。特殊情况下,如果构造器形参和类的属性同名时,就必须显示的使用”this.变量“的方式,表明此变量是属性,而非形参。
  3. this调用构造器

    1. 在类的构造器中,可以显示的使用”this(形参列表)“方式,调用指定的类的构造器
    2. 构造器中不能通过”this(形参列表)“方式调用自己
    3. 如果一个类中有n个构造器,则最多有n - 1个构造器可以使用”this(形参列表)“
    4. this(形参列表)必须声明在当前构造器的首行。
    5. 一个构造器中最多只能声明一个”this(形参列表)“来调用其他的构造器
    package exer;
    
    public class Person {
        private int age;
        private String name;
    
    
        public Person(){
            //在其他的构造器中使用this(形参列表)就不用重复声明,造成冗余
            System.out.println("假设这里有很多行的初始化语句");
            age = 18;
        }
        public Person(String name){
            //直接复用Person(){}构造器
            this();
            setName(name);
        }
        public Person(int age){
            //直接复用Person(){}构造器
            this();
            setAge(age);
        }
        public Person(int age, String name){
            //有了this(age)相当于直接复用了Person(age){}构造器
            this(age);
    //        setAge(age);
            setName(name);
        }
    
    
    
        public void setAge(int age){
            if(age > 0 && age < 130){
                this.age = age;
            }else{
                //不在范围内抛出异常
                throw new RuntimeException("传入的数据非法");
            }
    
        }
        public int getAge(){
            return age;
        }
        public void setName(String name){
            this.name = name;
        }
        public String getName(){
            return name;
        }
    }
    
    //******************************另一文件***************************
        
    package exer;
    
    public class PersonTest {
        public static void main(String[] args){
            Person p = new Person();
    
            System.out.println(p.getAge());
            p.setAge(21);
            System.out.println(p.getAge());
    //        p.setAge(-1);
    
            Person p1 = new Person(21, "bobo");
            System.out.println("name:" + p1.getName() + ", age: " + p1.getAge());
    
            //************************
            System.out.println("**************************");
    
            Person p2 = new Person("biggy");
            System.out.println("name:" + p2.getName());
        }
    
    }
    

    image-20210302170827599

    image-20210302171221330

  4. 练习

    image-20210302172349933

    1. addCustomer方法必须依照参数(名、姓)构造一个新的Customer对象,然后把它放到customer数组中。还必须把numberOfCustomer属性的值加1
    2. getNumberOfCustomer方法返回numberOfCustomers属性值
    3. getCustomer方法返回给出index参数的相关的客户
    4. 创建BankTest类,进行测试
    package bank;
    
    public class Account {
        private double balance;
    
        public Account(double init_balance){
            balance = init_balance;
        }
    
        public double getBalance() {
            return balance;
        }
        public void deposit(double amt){
            balance += amt;
        }
        public void withdraw(double amt){
            if(amt > balance){
                System.out.println("余额不足");
            }else{
                balance -= amt;
            }
        }
    
    }
    
    package bank;
    
    public class Customer {
        private String firstName;
        private String lastName;
        private Account account;
    
        public Customer(String f, String l){
            this.firstName = f;
            this.lastName = l;
        }
    
        public String getFirstName() {
            return firstName;
        }
        public String getLastName() {
            return lastName;
        }
        public Account getAccount() {
            return account;
        }
        public void setAccount(Account acct) {
            this.account = acct;
        }
    }
    
    package bank;
    
    public class Bank {
        private Customer[] customers;
        private int numberOfCustomer;
    
        public Bank(){
            //初始化用户数组
            customers = new Customer[10];
        }
    
        //lastName姓、firstName名,银行添加用户
        public void addCustomer(String f, String l){
            Customer cust = new Customer(f, l);
            customers[numberOfCustomer] = cust;
            numberOfCustomer++;
            //或
            //customers[numberOfCustomer++] = cust;
        }
        //获取客户的个数
        public int getNumberOfCustomer(){
            return numberOfCustomer;
        }
        //获取指定客户的信息
        public Customer getCustomer(int index){
            if(index < numberOfCustomer && index >= 0){
                //当角标满足在用户数组的范围内则返回指定用户
                return customers[index];
            }else{
                //否则返回空
            return null;
            }
        }
    }
    
    package bank;
    
    public class BankTest {
        public static void main(String[] args){
            double balance;
            //实例化Bank
            Bank bank = new Bank();
    
            //为bank添加新用户
            bank.addCustomer("bob","ma");
    
            /*通过bank对象下的获取指定用户的信息,
            * 为这个用户添加新账户,
            * 并且这个新账户的初始余额是1000
            * */
            //通过匿名对象创建新账户
            bank.getCustomer(0).setAccount(new Account(1000));
    
            //获取0号用户的信息后,存入500
            bank.getCustomer(0).getAccount().deposit(500);
            //获取用户当前余额
            balance = bank.getCustomer(0).getAccount().getBalance();
            //输出目前账户信息
            System.out.println("客户 " + bank.getCustomer(0).getFirstName() + " 的账户余额为:" + balance);
    
            //获取0号用户的信息后,取入1200
            bank.getCustomer(0).getAccount().withdraw(1200);
            //获取用户当前余额
            balance = bank.getCustomer(0).getAccount().getBalance();
            //输出目前账户信息
            System.out.println("客户 " + bank.getCustomer(0).getFirstName() + " 的账户余额为:" + balance);
    
            //输出目前银行的客户个数
            System.out.println("银行的客户个数为:" + bank.getNumberOfCustomer());
        }
    }
    
9.package关键字
  1. 为了更好的实现项目中类的管理,java提供包的概念;

  2. 使用package声明类或接口所属的包,声明在该文件的首行;

  3. 包——标识符,应当遵循标识符的命名规则(详情见文章20210103Java基础文末),做到见名知义。包命名的规范(xxx.yyy.zzz小写)

  4. 每”.“一次代表一层文件目录

  5. 同一个包下不能命名同名的接口、类;不同的包下可以命名同名的接口、类,但在同一个文件中引用不同包下的同名接口、类需要至少一个要以全类名的方式显示

  6. JDK中主要的包

    java.lang——包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能

    java.net——包含执行与网络相关炒作的类和接口

    java.io——包含能够提供多种输入、输出功能的类

    java.util——包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数

    java.text——包含一些java格式化相关的类

    java.sql——包含了java进行JDBC数据库编程的相关类、接口

10.import关键字
  1. import的作用,在一个java文件中导入其他已有的包

  2. 使用注意事项:

    1. 在源文件中显示使用的import结构导入指定包下的类、接口;

    2. import声明在包的声明类的声明之间;

    3. 如果需要导入多个结构,并列写出即可;

    4. 可以使用”xxx.*“的方式标识导入xxx包下的所有结构;

    5. 如果使用的类或接口时java.lang包下定义的,则可以省略import结构;

    6. 如果使用的类或接口时本包下定义的,则可以省略import结构;

    7. 如果在源文件中,使用了不同包下的同名类,则必须至少有一个类需要以全类名的方式显示;

    8. 使用”xxx.*“方式表明可以调用xxx包下的所有结构,但是如果使用的是xxx子包下的结构,则仍需要显示import;

    9. import static:导入指定的类或接口中的静态结构

      import static java.lang.System.out;
      public class importStaticTest {
          public static void main(String[] args){
              out.println("STAY ANGER!!!");
          }
      }
      
11.MVC设计模式
  1. MVC是常用的设计模式之一,将整个程序分为三个层次:视图模型层、控制器层与数据模型层。这种将程序输入输出、数据处理,以及数据展分离开来的设计模式使程序结构变得灵活而且清晰,同时也描述了程序各个对象之间的通信方式,降低了程序的耦合性。

  2. 模型层(model):主要处理数据

    数据对象封装 model.bean/domain

    数据库操作类 model.dao

    数据库 model.db

    视图层(view):显示数据

    相关工具类 view.util

    自定义view view.ui

    控制层(controller):业务处理层

    应用界面相关 controller.activity

    存放fragment controller.fraagment

    显示列表的适配器 controller.adapter

    服务相关 controller.service

    抽取的基类 controller.base

  3. MVC模型图

    img

STAY ANGER!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值