【123天】尚学堂高琪Java300集视频精华笔记(47-51)

第47集:面向对象20_多态、内存分析深化(模拟servlet中方法的调用)

  1. 示例代码

        package com.test047;
    
    public class HttpServlet {
        public void doGet(){
            System.out.println("doGet");
        }
    
        public void service(){
            System.out.println("service");
            doGet(); //此处相当于this.doGet(),调用的是子类MyServlet重写的方法。
        }
    }
        package com.test047;
    
    public class MyServlet extends HttpServlet {
        public void doGet(){
            System.out.println("MyServlet.doGet()");
        }
    }
    
        package com.test047;
    
    public class Test {
        public static void main(String[] args){
            HttpServlet s = new MyServlet();
            s.service();
        }
    }
  2. 内存分析

  3. 注意:

    1. 每个普通方法(甭管有参无参)里面,都有this和super两个隐式参数。

    2. 假如doGet是静态方法,结果就不是调用子类的doGet方法了,而是调用父类的doGet方法。

    package com.test
    
    public class HttpServlet {
        public void service(){
            System.out.println("service");
            doGet();
        }
        
        public static void doGet(){
            System.out.println("doGet");
        }
        
    }
    
    class MyServlet extends HttpServlet {
        
        public static void doGet(){
            System.out.println("MyServlet.doGet()");
        }
        
        public static void main(String[] args){
            HttpServlet a = new MyServlet();
            a.service();
        }
    
    }
    

第48集:面向对象21_抽象类、抽象方法

  1. 抽象方法特点
        只声明了方法,同时使用了abstract修饰,没有方法体!必须要子类来重写!

  2. 抽象类
        包含抽象方法的类,必须设计成抽象类!

  3. 抽象类的使用要点

    1. 通过抽象类,可以避免子类设计的随意性。

    2. 抽象类不能实例化,及不能用new来实例化抽象类。

    3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。

    4. 抽象类只能用来继承。

    5. 抽象方法必须被子类实现。

    6. 抽象类中可以有不抽象的方法。

    public class Test {
        public static void main(String[] args){
            Animal a = new Cat();
            a.breath();
        }
    }
    public abstract class Animal {
        String str;
        public abstract void run();
        public void breath(){
            System.out.println("呼吸");
            run();
        }
        
        public Animal(){
            System.out.println("动物");
        }
    }
    
    class Cat extends Animal{
        public void run(){
            System.out.println("猫步");
        }
    
    class Dog extends Animal{
        public void run(){
            System.out.println("狗跑");
        }
    }
    
    }

第49集:面向对象_22_接口详解

抽象程度对比

  1. 普通类:只有具体实现

  2. 抽象类:具体实现和规范(抽象方法) 都有!

  3. 接口:只有规范!

为什么需要接口?

  1. 为了实现多继承【注意,类只有单继承,但Java能通过接口实现多继承】

  2. 接口是两个模块之间通信的标准,通信的规范。如果能把你要设计的系统之间模块之间的接口定义好,就相当于完成了系统的设计大纲,剩下的就是添砖加瓦的具体实现了。大家在工作以后,做系统时往往就是使用“面向接口”的思想来设计系统。

接口和抽象类的区别?

  1. 接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。

  2. 抽象类还提供某些具体实现,接口不提供任何实现,接口中所有方法都是抽象方法。接口是完全面向规范的,规定了一批类具有的公共方法规范。

如何定义接口?

  1. 访问修饰符:只能是public或默认。

  2. 接口名:和类名采用相同命名机制

  3. extends:接口可以多继承

  4. 常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。

  5. 方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract.

    格式:
    [访问修饰符]  interface 接口名   [extends  父接口1,父接口2…]  {
    常量定义
    方法定义
    }

接口的本质

  1. 从接口的实现者角度看,接口定义了可以向外部提供的服务。

  2. 从接口的调用者角度看,接口定义了实现者能提供那些服务。

  3. 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。

  4. 接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。

  5. 接口的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所研究的,实际上就是如何合理的去抽象。

接口使用要点

  1. 子类通过implements来实现接口中的规范

  2. 接口不能创建实例,但是可用于声明引用变量类型。

  3. 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。;

  4. 接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。

  5. 接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。

package com.test049;

public interface MyInterface {
    //接口中只有常量和抽象方法
    public static final String MAX_GREAD = "GIRL";
    int MAX_SPEED = 123;
    public abstract void test01();
    int test02(int a,int b);
}

interface Attack {
    void attack();
}

class Plane implements Flyable{
    public void fly(){
        System.out.println("fly");
    }
}

class Man implements Flyable{
    public void fly(){
        System.out.println("man fly");
    }
}

class Stone implements Flyable,Attack{
    public void fly(){
        System.out.println("sss");
    }
    
    public void attack(){
        System.out.println("333");
    }
    
}
package com.test049;

public interface Flyable {
    int MAX_SPEED = 11000;
    int MIN_HEIGHT = 1;
    void fly();
}
package com.test049;

public class Test {
    public static void main(String[] args){
        Flyable f = new Stone();
        f.fly();
    }
}
package com.test049;

public interface InterfaceA {
    void aaa();
}

interface InterfaceB{
    void bbb();
}

interface InterfaceC extends InterfaceA,InterfaceB{
    void ccc();
}

class TestClass implements InterfaceC{
    public void aaa(){
        
    }
    
    public void bbb(){
        
    }
    
    public void ccc(){
        
    }
    
}

第50集:面向对象23_回调的实现、模板方法模式

###CallBack/Hook作用

在写到某一步骤,不知道咋写时,留出地方让别人写

###模板方法模式
package com.test050;
    
public class MyFrame {
    void paint(){
        System.out.println("CallBack");
    }
}
    
package com.test050;
    
public class PaintFrame {
    public static void drawFrame(MyFrame f){
        System.out.println("1");
        System.out.println("2");
        System.out.println("3");
    
        //画窗口
        
        f.paint();
        
        System.out.println("5");
        
    }
}
    
    
class GameFrame01 extends MyFrame{
    public void paint(){
        System.out.println("Game01");
    }
}
package com.test050;
    
public class Test {
    public static void main(String[] args){
        PaintFrame.drawFrame(new GameFrame01());
    }
}

第51集:面向对象24_内部类详解

内部类的定义(innerclasses)

一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内部定义,称为内部类。
 

内部类的作用

  1. 内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问【注意,并非不可访问】。

  2. 内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。 但外部类并不能直接访问内部类的内部属性。

内部类的使用场合

由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,通常内部类在只为所在外部类提供服务的情况下优先使用。
 

内部类的分类

  1. 成员内部类(可以使用private、proteted、public任意进行修饰。 类文件:外部类$内部类.class)

    1. 非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)

      1. 非静态内部类必须寄存在一个外部类对象里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。 非静态内部类对象单独属于外部类的某个对象。

      2. 非静态内部类可以使用外部类的成员,但是外部类不能直接访问非静态内部类成员。

        class outer {
            String type;
            
            class inner {
                String type;
                void HelloWorld(){
                    System.out.println("Hello World");
                }
            }
            
        }
        
        public class test {
            public static void main(String[] args){
                //HelloWorld a = new HelloWorld();
                //不行
                
                outer a = new outer();
                outer.inner b = a.new inner();
                //可行
                
                b.HelloWorld();
                
            }
        }
        
        class outer {
            String type;
            
            class inner {
                String type;
                void HelloWorld(){
                    //System.out.println(type);//指inner的type
                    //System.out.println(this.type);//指inner的type
                    //System.out.println(outer.this.type);//指outer的type
                    //若inner和outer无重名冲突,直接type就可以了
                }
            }
            
        }
                    
      3. 非静态内部类不能有静态方法、静态属性、静态初始化块。【即普通成员内部类只能有普通的方法和属性】

      4. 静态成员不能访问非静态成员:外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。

      5. 成员变量访问要点:

        • 内部类里方法的局部变量:变量名

        • 内部类属性:this.变量名

        • 外部类属性:外部类名.this.变量名

      6. 内部类的访问:

        1. 外部类中定义内部类:new InnerClass()

        2. 外部类以外的地方使用非静态内部类:

          Outer.inner  varname = OuterObject.new Inner()
2. 静态内部类
    1. 定义方式:
        
static  class   ClassName {
//类体
}
    1. 使用要点:
        1. 当一个静态内部类对象存在,并不一定存在对应的外部类对象。 因此,静态内部类的实例方法不能直接访问外部类的实例方法。
        2. 静态内部类看做外部类的一个静态成员。 因此,外部类的方法中可以通过:静态内部类.名字  访问静态内部类的静态成员。通过 new 静态内部类()访问静态内部类的实例。
        3. 在外部类的外面创建静态内部类:
            Outer.StaticInner  aInner = new  Outer.StaticInner();
  1. 匿名内部类

    
    适合那种只需要使用一次的类。比如:键盘监听操作等等。语法:

        

    new  父类构造器(实参类表) 实现接口 () {
        //匿名内部类类体!
    }
    this.addWindowListener(new WindowAdapter(){
     
    @Override
    public void windowClosing(WindowEvent e) {
    
    System.exit(0);
    
    }
            
            });
  2. 局部内部类

    定义在方法内部。作用域只限于本方法。用的非常少。
    

示例代码

package test051;

//import test051.Face.Nose;

public class Outer {
    public static void main(String[] args){
        //非静态内部类调用
        Face a = new Face();
        Face.Nose n = a.new Nose();
        n.breath();
        //静态内部类调用
        Face.Ear m = new Face.Ear();
        m.listen();
    }
}

class Face {
    int type;
    String shape = "瓜子脸";
    static String color = "red";
    
    class Nose{
        
        void breath(){
            System.out.println("呼吸");
        }
    }
    
    static class Ear{
        void listen(){
            //System.out.println(shape);//不可访问外部类普通属性
            System.out.println("我在听");
            //System.out.println(color);//可访问外部类静态属性
        }
    }
    
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值