Java基础(二)

一、件生命周期:

软件生命周期: 软件的产生直到 废的整个过程.

软件生命周期内有:问题定义, 可行性分析, 总体描述, 系统设计,编码, 调试和测试, 验收与运行, 维护升级到废弃等阶段

————————————————————————————–

1):问题的定义及规划: 此阶段是软件开发方与需求方共同讨论,主要确定软件的开发目标及其可行性。

2):需求分析: 在确定软件开发可行的情况下,对软件需要实现的各功能进行详细分析。需求分析阶段是一个很重要的阶段,这一阶段做得好,将为整个软件开发项目的成功打下良好的基础。

3):软件设计: 此阶段主要根据需求分析的结果,把整个软件系统划分为大大小小的多个模块,设计出每一个模块的具体结构。如系统框架设计,数据库设计等。软件设计一般分为总体设计和详细设计。

4):程序编码: 此阶段是将软件设计的结果转换成计算机可运行的程序代码。在程序编码中必须要制定统一,符合标准的编写规范。以保证程序的可读性,易维护性,提高程序的运行效率。

5):软件测试: 在软件设计完成后要经过严密的测试,以发现软件在整个设计过程中存在的问题并加以纠正。整个测试过程分单元测试(白盒)、集成测试(黑盒,功能测试、强度性能测试)以及系统测试三个阶段进行。测试的方法主要有白盒测试和黑盒测试两种。在测试过程中需要建立详细的测试计划并严格按照测试计划进行测试,以减少测试的随意性。

6):运行维护: 安装部署软件系统,修复软件中存在的bug和升级系统。在软件开发完成并投入使后,由于多方面的原因,软件不能继续适应用户的要求。要延续软件的使用寿命,就必须对软件进行维护。软件的维护包括纠错性维护和改进性维护两个方面

二、软件设计原则:

为了提高软件的开发效率,降低软件开发成本,一个优良的软件系统应该具有以下特点:

1,可重用性:遵循DRY原则,减少软件中的重复代码。

2,可拓展性:当软件需要升级增加新的功能,能够在现有的系统架构上方便地创建新的模块,而不需要改变软件现有的结构,也不会影响以及存在的模块。

3,可维护性:当用户需求发生变化时,只需要修改局部的模块中的少量代码即可。

 

如何让软件系统达到上述的特点,我们对模块的要求:

1):结构稳定性:在软件设计阶段,把一个模块划分为更小的模块时,设计合理,使得系统结构健壮,以便适应用户的需求变化。

2):可拓展性:当软件必须增加新的功能时,可在现有模块的基础上创建出新的模块,该模块继承了原有模块的一些特性,并且还具有一些新的特性,从而实现软件的可重用和可拓展性。

3):可组合性:若干模块经过组合,形成大系统,模块的可组合性提高软件的可重用和可维护性,并且能简化软件开发过程。

4):高内聚性:内聚,强调一个模块内的功能联系,每个模块只完成特定的功能,不同模块之间不会有功能的重叠,高内聚性可以提高软件的可重用性和可维护性。

5):低耦合性:耦合,强调的是多个模块之间的关系,模块之间相互独立,修改某一个模块,不会影响到其他的模块。低耦合性提高了软件的可维护性。

举例:洗袜子

面向过程:

单身汪版:

   1.倒一盆水

   2.把你的臭袜子扔进去

   3.倒洗衣粉泡一泡

   4.搓一搓晾起来

 

面向对象:

虐汪版: 找一个对象(女朋友)

    帮你把臭袜子洗干净给你  

 

自虐版:找一个对象(女朋友)

    你女朋友把他的袜子给你还是你自己洗这时你就是那个对象

 

自力更生版:找一个对象(洗衣机)交给洗衣机这个对象来帮你完成

 

介绍一下类和对象如何创建

 

1. 一个文件里面是可以有多个class的,但是只有一个class可以修饰为public, 这个修饰为public的class必须和文件名保持一致

2. 一个.java文件中有几个class, 就会生成几个.class字节码文件

3. 如果一个文件里面有多个类,如果需要main函数,main函数应该书写在和文件名一致的那个类里面

在代码中打印一次

1):对象的打印操作:

     打印对象的时候,打印出来的效果,如:Servant@3294e4f4.

     类的名称@十六进制的hashCode.

     其实,我们打印对象,往往关系的是该对象中的数据是多少,期待讲解Obejct的toString方法.

2):对象比较操作:

     == :对于基本数据类型来说,比较的是值.

               对于引用数据类型来说,比较的是在内存中的地址值.

                每次使用new关键字,都表示在堆值新开辟一块内存空间,不同的内存空间,地址值不同.

     需求:如果对象拥有完全相同的数据,我就想让他们相等. 期待:Object的equals方法.

3):对象的生命周期:

     对象什么时候出生:每次使用new关键字的时候,就会在内存开辟新的空间,此时对象开始存在.

     对象的结束:当堆中的对象,没有被任何变量所引用,此时该对象就成了垃圾,就等着垃圾回收器(GC)来回收该垃圾,当被回收的时候,对象被销毁了,回收垃圾的目的,释放更多的内存空间.

 

单利设计模式

  /*

     * 单利设计模式:

     * 使当前对象全局实例唯一

     * 无论如何创建对象只有一个地址(实例唯一)

     * 饿汉式

     * 1.设计一个本类类型的静态私有属性,并且初始化;

     * 2.私有构造方法

     * 3.提供一个公有静态的方法来获取获取当前对象

     * private static HungrySingleDemo instance = new HungrySingleDemo();

private HungrySingleDemo(){

 

}

    public static HungrySingleDemo getInstance(){

return  instance;

}

     * 懒汉式:

     * 1.设计一个当前类类型的静态私有属性

     * 2.私有化构造方法

     * 3.提供一个静态获取当前对象的方法

     *  进行判断

     *    第一次 判断当前对象时候是null

     *       就创建创建对象返回

     *    第二次  判断当前对象时候是null

     *      不是那就直接返回

    private static LazySingleDemo instance;

private LazySingleDemo(){

 

}

public static LazySingleDemo getInstance(){

//判断是不是第一次获取

if(instance == null){

instance = new LazySingleDemo();

}

return instance;

}

     * 懒汉和饿汉:

     * 1.相同点:都是单利设计模式

     * 2.不用点:饿汉是先创对象然后在获取,比较直接

     *          懒汉是先判断然后在返回对象

     * ps:这两种设计模式在线程中有一个会出现问题,无法保证唯一

     *          

     * 简化版本:

     *     private 类名(){} 私有化构造方法

     *     public static final 类名 对象 = new 类名();

     *     //final最终的 常量静态常量

     *

     * ps:工具类 –> 方法都是静态方法

     * 只能通过类名的方式来获取类中方法,所以当前类是不能创建对象

     * 一定要将当前工具类的构造方法私有化

     *

     *

     *

     *

     *

     */

  public static void main(String[] args) {

  //饿汉模式 –> 一个国家只能有一个主席(正)

  HungrySingleDemo hsd1 = HungrySingleDemo.getInstance();

  HungrySingleDemo hsd2 = HungrySingleDemo.getInstance();

  System.out.println(hsd1 == hsd2);

  //懒汉模式

  LazySingleDemo lsd1 = LazySingleDemo.getInstance();

  LazySingleDemo lsd2 = LazySingleDemo.getInstance();

  System.out.println(lsd1 == lsd2);

}

 

 

}

什么是封装(面向对象三大特征之一)/p>

① 把对象的状态和行为看成一个统一的整体,将二者存放在一个独立的模块中();

② ”信息隐藏“, 把不需要让外界知道的信息隐藏起来,尽可能隐藏对象功能实现细节,向外暴露方法,保证外界安全访问功能;  把所有的字段使用private私有化,不准外界访问,把方法使用public修饰,允许外界访问.

 把所有数据信息隐藏起来,尽可能隐藏多的功能,只向外暴露便捷的方法,以供调用.

属性既然因此,所以需要提供访问 getter和setter方法

 

举那个狗能修改年龄的问题顺便说get和set  顺带说一下this

 

什么是继承关系:

基于某个父类对对象的定义加以拓展,而产生新的子类定义,子类可以继承父类原来的某些定义,也可以增加原来父类所没有的定义,或者重写父类中的某些特性。

从面向对象的角度上说:继承是一种从一般到特殊的关系,是一种“is a”的关系,即子类是对父类的拓展,是一种特殊的父类,比如:狗是动物的一种特殊情况,狗属于动物。

————————————————————————–

在Java语言中,存在多个类的时候,我们使用”extends”关键字来表示子类和父类之间的关系.

语法格式: 在定义子类的时候来表明自己需要拓展于哪一个父类.

public  class  子类类名    extends    父类类名

{

         编写自己特有的状态和行为

}

————————————————————————–

Java中,类和类之间的继承关系只允许单继承,不允许多继承.

也就是说一个类A,只能有一个直接的父类,不能出现类A同时继承于

类B和类C.

  但是,Java中允许多重继承.

 多重继承例子

动物有胎生动物卵生动物之分,胎生动物有老虎,老虎又分华南虎,

东北虎,孟加拉虎等。

————————————————————————–

在Java中除了Object类之外,每一个类都有一个直接的父类.

比如:class Student extends Person{}

我们就说此时Student的直接父类是Person.

问题: class Person{} ,此时Person的父类又是谁/p>

Object类是Java语言的根类(老祖宗,任何类都是Object的子类.)

class  Person{} 等价于 class Person extends Object{}

 Object类要么是一个类直接父类,要么是一个类间接父类.

————————————————————————–

继承关系的作用:

                     1):解决了代码的重复问题.

                     2):真正的作用,表示出一个体系.

先写父类还是先写子类:

   一般的,我们在开发工程中先编写多个自定义类,写完之后,发现多个类之间存在共同的代码,此时可以抽去出一个父类.

   我们以后做开发,都是基于框架/组件来做的,我们是在别人的基础之上,继续做开发.

    好比,别人提供毛坯房,我们只需要在毛坯房的基础之上装修,就可以使用.

    以后,我们定义新的类去继承于框架中/组件中提供的父类.

子类继承父类之后,可以拥有父类的某一些状态和行为(子类复用了父类的功能或状态).

子类到底继承了父类的哪些成员(根据访问修饰符来判断):

      1):如果父类中的成员使用public修饰,子类继承.

      2):如果父类中的成员使用protected修饰,子类也继承,即使父类和子类不在同一个包中.

      3):如果父类和子类在同一个包中,此时子类可有继承父类中 缺省修饰符的成员.

      4):如果父类中的成员使用private修饰,子类打死都继承不到.因为private只能在本类中访问.

      5):父类的构造器,子类也不能继承,因为构造器必须和当前的类名相同

说下super和重写 还有子类实例化的过程

 

 

 

多态是什么呢,多态就是你把我和我姐生出来,然后我和我姐都可以成长,但是同样都是成长但是,我姐长好看了,我长丑了,这就是多态.但是如果要实现多态的话,必须得是您的亲子女,而且行为必须一样,但是做出行为之后,有不同的结果.

 

如:设计一个员工类,其中有计算员工薪水的方法。

  根据员工职务的不同,薪水计算方式也不同。

    员工类型              薪水构成

—————————————————–

 经理  manager            底薪salary+ 奖金bonus

 

  销售人员 sales                底薪 + 提成pushmoney

 普通员工  staff                  底薪 + 补贴(车补、饭补等等)subsidy

 

然后,设计一个测试类,测试一下。

场景:年终,领导找员工谈话,让员工介绍自己的薪水。

员工类:employee  父类

属性 : 底薪: salary

       名字: name

行为: 计算底薪 –>返回值类型 可有可无

经理

销售人员

普通员工

 

多态:多态允许程序中出现重名的现象,JAVA语言中含有方法重载与对象多态两种形式的多态.

方法重载:在一个类中,允多个方法使用一个名字,但方法的参数不同,返回值不同,完成的功能也不同

对象多态:子类对象可以与父类对象进行相互转换,而且根据其使用的子类的不同,完成功能也不同

所谓多态就是指同一操作被不同的对象所触发,产生的结果是不同的.例如当听到cut 这个单词,理发师的表现是剪发,而演员的表现是停止表演

同一个事物被不同对象所触发,产生的结果是不同的

 

发生多态的前提:

1.可以是继承关系也可以是实现关系

2.要有方法的重载

3.要有父类引用指向子类对象

 

多态在实际中如何使用/p>

多态的作用:当把不同的子类对象都当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异,从而写出通用的代码达到通用编程,以适应需求的不断变化,从而达到减少代码的作用

 

二、对象的向上转型和向下转型

2.1对象的向上转型

子类对象赋值给父类类型的引用时,会自动将子类对象对应的类型提升为父类类型。

语法:父类类型 引用 = new 子类构造方法();

特点:此时,该引用只能调用父类中所有可见的属性和方法,不能调用子类特有的属性和方法。

2.2对象的向下转型

将父类对象强制转换为子类类型的过程。

语法:子类类型 引用 =  (子类类型)父类对象;

特点:1、此时,该引用可以调用子类特有的方法,同时还可以调用从父类中继承过来的所有方法。

      2、在进行强制类型转换之前,一定要使用instanceof关键字判断一下,否则,很容易抛出“ClassCastException”(类型强制转换的异常)。

 

instanceof语法:

    对象 instanceof 类型

结果:boolean

      true:之前的对象是属于之后类型的实例

      false:之前的对象不是之后类型的实例

 

5.1抽象类

语法:

访问权限修饰符 abstract class 类名{

//普通属性

//普通方法

        //抽象方法

      }

 

5.2抽象方法:

语法:

访问权限控制符 abstract 返回值类型 方法名(形参列表);

 

 

接口: 而接口则是 “有什么”(has – a),意思是有什么功能,比如:鸟会飞,飞机也会飞,而这两个不是属于同一个类,飞行的方式也不同,所以需要接口标准来将两个不一样的类来实现同一个功能;

语法:访问权限修饰符  interface 接口名{

  //全局常量 (默认修饰符:public static final)

 

          //抽象方法 (默认的修饰符是:public abstract)

}

接口和抽象类的区别:

相同点:

1):都位于继承的顶端,用于被其他实现或继承。

2):都不能实例化。

3):都可以定义抽象方法,其子类/实现类都必须覆写这些抽象方法。  

不同:

1):接口没有构造方法,抽象类有构造方法。

2):抽象类可包含普通方法和抽象方法,接口只能包含抽象方法(Java8之前);

3):一个类只能继承一个直接父类(可能是抽象类),接口是多继承的并且只支持一个类实现多个接口(接口弥补了Java的单继承)。

4):成员变量:接口里默认是public static final,抽象类是默认包权限。

5):方法:接口里默认是public abstract,抽象类默认是默认包访问权限。

 

Java8中接口新特性

//JDK1.8接口新特性

public interface InterFaceForJDK {

  

      //抽象方法

  void show();

  //1.使用default修饰,默认是用是public

  //接口实现类调用的方法

  default void showInfosDefault(){

  System.out.println(“接口中实现的default方法”);

  }

 

  //2.使用static修饰,默认是用public

   //直接通过接口调用

  static void  showInfosStatic(){

  System.out.println(“接口中实现的static方法”);

  }

}

剪刀石头布

/**

 * 玩家类

 

 * @author JKMaster

 *所有的类直接或间接父类都是Object,所以所有的类都隐藏着继承Object

 *public class  Player extends Object{}

 */

public class Player {

     //封装 就是属性不对外直接提供访问

 private String name;

 private int  total; //总局数

 private int  victory; ///胜场

 

 

}

import java.util.Scanner;

 

/**

 * 电脑类

 * @author JKMaster

 *

 */

public class Computer {

       //一个类需要使用另外一个类的属性或行为时

   //1.作为当前类的属性存在

   //2.作为方法的参数存在

   private Player player; // 因为是引用类型,所以默认值是null

   //当前类中是可以使用当前属性的,但是创建类的对象时必须赋值

   public  Computer(Player player) {

   this.player = player;

   }

   /**

    * 游戏主界面

    */

   public void menu() {

   System.out.println(“************************************************************”);

   System.out.println(“欢迎”+player.getName()+”进入猜拳游戏”);

   System.out.println(“1.石头     2.剪刀     3.布     0.退出”);

   System.out.println(“************************************************************”);

   System.out.println(“请输入数字:”);

   }

   

   //模拟电脑出拳

   public int computerRand() {

   return  (int)(Math.random()*3+1); // [1,4) –> 1-3

   }

   /**

    * 主逻辑

    */

   public void menuLogic() {

    //设置一些变量,这些变量会进行运算并将结果存储到相对应的属性中

    int win = 0; //得到的比较点数(猜拳的差值)

    int STotal = 0; //总场数

    int SVictory = 0; //胜场

    int player_choose = 0 ; //玩家点数(出拳)

    int computer_choose = 0 ; //电脑点数(出拳)

    Scanner input = new Scanner(System.in);

    while(true) {//死循环,在不确定完多少局的前提下

     //主界面

     menu();

     //玩家输入

     player_choose = input.nextInt();

     //可以进行一次判断 判断数据是输入正确

     if(0 == player_choose) {//结束游戏

       return ;

     }

     //电脑输入

     computer_choose = computerRand();

     //已经开始玩了,所以总局数要+1

     player.setTotal(++STotal);

     //做差值

     win = player_choose – computer_choose; // 得到一个差值

     switch (win) {

case -1:

case  2:

System.out.println(“恭喜  你赢了….赢了”);

System.out.println();//换行 不让打印 距离太近

player.setVictory(++SVictory);//胜场+1

break;

case  0:

System.out.println(“平局”);

System.out.println();//换行 不让打印 距离太近

break;

 

default:

System.out.println(“你输了哈哈哈哈哈…. 再来);

System.out.println();//换行 不让打印 距离太近

break;

}

    }

    

   }

   

   /**

    * 显示结果

    */

   public void show() {

   System.out.print(“*ttt排行榜n”);

   System.out.println(“************************************************************”);

   System.out.println(“姓名tt总局数tt赢场tt胜率tt”);

  double win = ((double) (player.getVictory()) / (double)(player.getTotal()))*100;

  System.out.println(player.getName()+”tt”+player.getTotal()

       +”tt”+player.getVictory()+”tt”+String.format(“%.2f”, win));

     //String.format(“%.2f”, win)  —> 格式化字符串,当前方式static修饰的方法

    // 第一个参数是格式化控制符(类似于C中scanf函数)  第二个是参数

      // 格式化控制符需要和参数一一对应

   }

 

}

/**

 * 剪刀石头布

 * @author JKMaster

 *

 */

public class Test {

 

public static void main(String[] args) {

Player p = new Player();

//直接给值了

p.setName(“小明”);

Computer c = new Computer(p);

c.menuLogic();

c.show();

 

}

 

}

 

 

 

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年7月2日
下一篇 2019年7月2日

相关推荐