zoukankan      html  css  js  c++  java
  • 《Java程序设计》第四周学习总结

    20145224-陈颢文 《Java程序设计》第四周学习总结

    教材学习内容总结

    第六章 继承与多态

    ·继承就是面向对象中,子类继承父类,避免重复的行为定义。重复再程序设计上是非常不好的信号,因为其大大增加了修改维护程序的成本。要避免重复,就可以把相同的代码程序提升为父类:

    public class Role {
        private String name;
        private int level;
        private int blood;
    
        public int getBlood() {
            return blood;
        }
        public void setBlood(int blood){
            this.blood = blood;
        }
        public int getLevel(){
            return level;
        }
        public void setLevel(int level){
            this.level = level;
        }
        public String getName(){
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    public class SwordsMan extends Role{
        public void fight(){
            System.out.println("挥剑攻击");
        }
    }
    
    public class Magician extends Role {
        public void fight(){
            System.out.println("魔法攻击");
    
        }
    public void cure() {
        System.out.println("魔法治疗");
    }
    }
    

    ·以下程序,虽然没有定义getName()、getLevel()、getBlood()但从Role中继承就可以直接使用。

    public class RPG {
        public static void main(String[] args) {
            demoSwordsMan();
            demoMagician();
    
        }
    
        static void demoSwordsMan() {
            SwordsMan swordsMan = new SwordsMan();
            swordsMan.setName("Justin");
            swordsMan.setLevel(1);
            swordsMan.setBlood(200);
            System.out.printf("剑士:(%s,%d,%d)%n",swordsMan.getName(),
                    swordsMan.getLevel(),swordsMan.getBlood());
        }
    
        static void demoMagician() {
            Magician magician = new Magician();
            magician.setName("Monica");
            magician.setLevel(1);
            magician.setBlood(100);
            System.out.printf("剑士:(%s,%d,%d)%n", magician.getName(),
                    magician.getLevel(), magician.getBlood());
        }
    
        }
    
    

    ·若是希望使用单一接口操作多种类型的对象,那么就可以运用多态来完成:

    public class RPG {
        public static void main(String[] args) {
    
            SwordsMan swordsMan = new SwordsMan();
            swordsMan.setName("Justin");
            swordsMan.setLevel(1);
            swordsMan.setBlood(200);
    
    
            Magician magician = new Magician();
            magician.setName("Monica");
            magician.setLevel(1);
            magician.setBlood(100);
    
            showBlood(swordsMan);
            showBlood(swordsMan);
    
        }
    
        static void showBlood(Role role) {
            System.out.printf("%s 血量 %d%n", role.getName(), role.getBlood());
        }
    }
    
    

    ·重新定义是指在继承父类之后,定义与父类中相同的方法部署,但执行内容不同。

    首先要在Role中重新定义fight()的实际意义

    public class Role {
        private String name;
        private int level;
        private int blood;
        public void fight(){}
    ···
    
    

    其次在主程序中调用fight

    ···
    
           drawFight(swordsMan);
            drawFight(magician);
    
        }
    
        static void drawFight(Role role) {
            System.out.print(role.getName());
            role.fight();
    ···
    

    ·如果某方法区块中真的没有任何程序代码操作,可以使用abstract表示该方法为抽象方法,不用撰写{ }区块,直接“;”结束即可。
    ·含有抽象方法的类,一定要在class前标示abstract;子类如果继承抽象类,意识继续标示abstract,另一种就是操作方法。

    ·protect成员:在Role中name。level.blood被定义为private,无法直接在子类中存取,因此可让子类直接定义为protected类型。被声明protected成员之后,相同包中的类可以直接存取,不同包的类可以在继承后的子类直接存取。
    定义如下:

    public class Role {
        protected String name;
        protected int level;
        protected int blood;
    ··· 
    

    ·如果想取得父类中的方法定义,可以在调用方法前,加上super关键字;
    ·重新定义方法要注意,对于父类中的方法权限,只能扩大不能缩小。若原来成员public,子类中重新定义时不可为private或protected。
    ·如果累有继承关系,在创建子类实例后,会先进行父类定义的初始流程,再进行子类中定义的初始流程。
    ·构造函数可以重载,父类中可重载多个构造函数,如果子类构造函数中没有制定执行父类中那个构造函数,会默认调用父类中无参数构造函数。
    ·final:在指定变量值后,如果不想再改变变量值,可以在声明变量时加上final。
    ·如果对象数据成员被声明为final,一定要有对该数据成员指定值的动作!
    ·class前也可以加上final关键字,表明这个类是最后一个类,不会有子类,不能继承。
    ·子类只能继承一个父类,如果定义类时没有使用extends关键字指定继承任何类,那一定是继承java.lang.Object。
    ·定义ArrayList类,可以不限长度地收集对象。
    以下实例时将收集访客名称转为大写后显示:

    public class RPG {
        public static void main(String[] args) {
    
            SwordsMan swordsMan = new SwordsMan();
            swordsMan.setName("Justin");
            swordsMan.setLevel(1);
            swordsMan.setBlood(200);
    
    
            Magician magician = new Magician();
            magician.setName("Monica");
            magician.setLevel(1);
            magician.setBlood(100);
    
           drawFight(swordsMan);
            drawFight(magician);
    
        }
    
        static void drawFight(Role role) {
            System.out.print(role.getName());
            role.fight();
        }
    }
    

    ·toString的定义代码为:

    public String toString(){
       return getClass().getName()+ “@”+Integer.toHexString(hashCode());
    }
    
    ·equals()的定义代码为:
    public boolen equal(Object obj){
      return (this==obj);
    }
    

    ·创建对象会占据内存,如果程序执行流程中已无法再使用某个对象,该对象就会被当作垃圾,由GC认定垃圾对象然后垃圾收集释放。
    在用户输入、显示结果等环节未定,也可以编写代码片段,运用抽象方法:

    public abstract class GuessGame {
        public void go(){
            int number = (int) (Math.random()*10);
            int guess;
            do {
                print("输入数字'");
                guess = nextInt();
                
            } while(guess != number);
            println("猜中啦");
            
            
        }
    
        public  void println(String text){
            print(text + "
    ");
            
        }
        public abstract void print(String text);
        public abstract int nextInt();
                
        
    }
    
    import java.util.Scanner;
    
    public class ConsoleGame extends  GuessGame {
        private  Scanner scanner = new Scanner(System.in);
        @Override
        public void print(String text){
            System.out.print(text);
        }
    
        @Override
        public void println(String text){
            System.out.println(text);
    
        }
        @Override
        public int nextlnt() {
            return scanner.nextlnt();
        }
    }
    
        public static void main(String[] args) {
            GuessGame game = new ConsoleGame();
            game.go();
        }
    }
    

    ·区别于继承,接口定义的是行为,可以使用interface关键字定义。
    ·以下程序代码定义了接口,可以用于定义行为但不定义操作

    public interface Swimmer {
        public abstract void swim();
    
    }
    
    

    ·对接口中定义的方法有两种:
    1.操作接口中定义;
    2.再度将该方法标示为abstract;

    public class Human implements Swimmer {
        private String name;
        public Human(String name){
            this.name = name;
        }
        public String getName(){
            return name;
            
        }
        @Override
        public void swim(){
            System.out.printf("人类%s游泳%n",name);
        }
    }
    
    

    ·Submarine操作了Swimmer,但没有继承Fish。

      public class Submarine implements Swimmer {
            private String name;
    
            public Submarine(String name) {
                this.name = name;
    
            }
    
            public String getName() {
                return name;
            }
    
            @Override
            public void swim() {
                System.out.printf("潜水艇%s潜行%n", name);
            }
    
    
        }
    

    ·多态语法的判断:判断“右边是不是拥有左边的行为”或者“右边对象是不是操作了左边接口”
    ·只要操作接口对象一直,都可以使用doSwim的方法,提高了系统的可维护性。
    程序范例如下:

    public class Ocean {
        public static void main(String[] args) {
            doSwim(new Ugly("尼莫"));
            doSwim(new Shark("兰尼"));
            doSwim(new Human("贾斯汀"));
            doSwim(new Submarine("黄色一号"));
    
    
    
        }
    
        static void doSwim(Swimmer swimmer){
            swimmer.swim();
        }
    }
    
    

    ·为了满足用户多需求,例如满足有的东西即会飞又会游泳,可以使用interface定义Flyer接口

    public interface Flyer {
            public abstract void fly();
    
        }
    
    

    ·定义Seaplane操作Swimmer与Flyer接口;类可以继承,并能操作某些接口,因此它即能飞又能又能游;

    public class Seaplane implements Swimmer,Flyer {
        private String name;
        public Seaplane(String name){
            this.name = name;
        }
        @Override
        public void fly(){
            System.out.printf("海上飞机   %s  在飞  %n",name);
    
        }
        @Override
        public void swim(){
            System.out.printf("海上飞机%s  航行海绵%n",name);
        }
    }
    
    
    

    ·定义游泳选手是一种人,同时拥有Swimmer的行为

    public class Human {
        protected String name;
        public Human(String name){
            this.name = name;
    
        }
    
        public String getName(){
            return name;
        }
    }
    
    
    public class SwimPlayer extends Human implements Swimmer {
        public SwimPlayer(String name){
            super(name);
            
        }
        
        @Override
        public void swim(){
            System.out.printf("游泳选手 %s 游泳 %n",name );
        }
    }
    

    ·接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为。

    public interface Diver extends Swimmer {
        public abstract void dive();
    }
    
    
    public class Boat implements Swimmer {
        protected String name;
        public Boat(String name){
            this.name = name;
        }
        
        @Override
        public void swim(){
            System.out.printf("船在水面 %s 航行 %n", name);
        }
        
    
    }
    
    
    

    ·定义潜水艇即在浅海游泳,也可以在深海潜行

    public class Submarine extends Boat implements Diver {
        public Submarine(String name){
            super(name);
        }
        
        @Override
        public void dive(){
            System.out.printf("潜水艇 %s 潜行%n",name);
        }
    }
    

    ·在java中可使用interface来定义抽象的行为与外观,接口中的方法可声明为public abstract;
    例如:

    public interface Swimmer {
        public abstract void swim();
    
    }
    
    

    ·接口中的方法没有操作时,必须是公开且抽象的。

    ·枚举常数范例:

    public interface Action {
        public static final int STOP = 0;
        public static final int RIGHT = 1;
        public static final int LIFT = 2;
        public static final int UP = 3;
        public static final int DOWN = 4;
    }
    
    

    ·在枚举常数时要使用“=”指定值,否则会编译出错。
    ·Some与Other定义的execute()
    1.表示不同行为,Service有两个不同的操作方法,Some与Other在名称上有所不同。
    2.表示相同行为,可以定义一个父接口,当定义execute()方法,而some与other继承该接口,各自定义自己的doSome()与doOther()方法。

    ·撰写java时有临时某个类或操作某个接口并建立实例,因为只用一次所以不需要为这些类定义名称,此时可以运用匿名类
    语法:
    new 父类()|接口(){
    //类本体操作
    };

    ·操作接口范例;
    Some some = new Some() { //操作Some接口并直接产生实例
    public void doService(){
    System.out.println(“do something”);
    }
    };

    接口应用举例
    ·建立Client对象封装信息

    
    public class Client {
        public final String ip;
        public final String name;
        public Client(String ip,String name){
            this.ip = ip;
            this.name = name;
        }
    }
    
    

    ·若程序其他部分希望在Client加入或移除时可以收到通知,可以将Client加入或移除的信息包装为ClientEvent;

    public class ClientEvent {
        private Client client;
        public ClientEvent(Client client){
            this.client = client;
        }
        
        public String getName(){
            return client.name;
        }
        
        public String getIp(){
            return client.ip;
        }
        
        
    }
    
    

    ·新增和移除时可以用到

    public interface ClientListener {
        void clientAdded(ClientEvent event);
        void clientRemoved(ClientEvent event);
    }
    
    
    import java.util.ArrayList;
    public class ClientQuene {
        private ArrayList clients = new ArrayList();
        private ArrayList listeners = new ArrayList();
        
        public void addClientListener(ClientListener listener){
            listeners.add(listener);
            
        }
        public void aVoid(Client client){
            clients.add(client);
            ClientEvent event = new ClientEvent(client);
            for(int i=0;i<listeners.size();i++){
                ClientListener listener = (ClientListener)listeners.get(i);
                listener.clientAdded( event);
            }
        }
        
        public void remove(Client client){
            clients.remove(client);
            ClientEvent event = new ClientEvent(client);
            for (int i=0;i< listeners.size();i++){
                ClientListener listener = (ClientListener) listeners.get(i);
                listener.clientRemoved(event);
            }
        }
    }
    
    

    教材学习中的问题和解决过程

    一开始我还是照着课本上的代码不停地码上去,结果发现到了第七章,有的代码就编译不通过,后来就只能把课本看了一遍再修改代码了。这个周末本来打算把每个章节课后题都编一下,但由于要备考计算机二级,就只编写了一下两个:

    public class gongyingzi1000495 {
        public static void main(String[] args) {
            int m = 1000;
            int n = 495;
            while (true){
                m = m % n;
                if (m == 0){
                    System.out.println(n);
                    break;
                }
                n = n % m;
                if (n == 0){
                    System.out.println(m);
                    break;
                }
            }
        }
    }
    
    public class Armstrong {
        public static void main(String[] args) {
            for (int i = 1;i <= 9;i++){
                for (int j = 1;j <= 9;j++){
                    for(int k = 1;k <= 9;k++){
                        if (i*i*i + j*j*j + k*k*k == i*100 + j*10 + k){
                            System.out.println(i*100 + j*10 + k);
                        }
                    }
                }
            }
        }
    }
    

    本周代码托管截图




    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 4500行 30篇 350小时
    第一周 150/150 1/1 15/15
    第二周 200/350 1/2 20/35
    第三周 300/650 1/3 25/60
    第四周 350/1000 1/4 30/90

    参考资料

  • 相关阅读:
    VFIO PF SRIOV IOMMU UIO概念解释、关联
    集群节点间网络通信TIPC
    1. C语言中的数据结构.md
    第三讲. COTS包交换介绍
    SYSTick 定时器
    热电偶基础知识介绍-04
    附录1· 初识Linux操作系统
    热电偶冷端补偿
    珍惜是最宝贵的财富。
    CSS 设置标题文字只显示一行,多余显示省略号
  • 原文地址:https://www.cnblogs.com/20145224kevs/p/5327093.html
Copyright © 2011-2022 走看看