Java 面向对象

Java 面向对象

回顾方法的定义

  • 修饰符

  • 返回类型

  • break和 return的区別

    break:用来结束循环。 return:方法结束,返回一个结果。

  • 方法名:注意命名规范 , 见名知意

  • 参数列表

  • 异常抛出

回顾方法的调用

  • 静态方法
  • 非静态方法:需要构造实例化对象,进行调用。
  • 形参和实参
  • 值传递和引用传递
    • 值传递:在方法被调用时,实参通过形参把它的内容副本传入方法内部,此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。
    • 引用传递:”引用”也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向同一块内存地址,对形参的操作会影响的真实内容。
  • this关键字
    • this指向自己的引用,即当前方法所在的对象。它的一个主要作用是要将自己这个对象当作参数,传送给别的对象中的方法。

类与对象的创建

类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。

对象是抽象概念的具体实例。

语法:

[类的修饰符] class 类名称 [extends 父类名称][implements 接口名称列表]
{
    
	变量定义及初始化;
	方法定义及方法体;
}

什么是面向对象

  • 面向对象编程( Object- Oriented Programming,OOP)

  • 面向对象编程的本质: 以类的方式组织代码,以对象的组织(装)数据。

  • 抽象

  • 三大特性

    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。

  • 从代码运行角度考虑是先有类后有对象。类是对象的模板。

创建与初始化对象

  • 使用new关键字创建对象。

  • 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。

  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下俩个特点:

    • 必须和类的名字相同。
    • 必须没有返回类型,也不能写void。
  • 构造器必须要掌握。

例子:

public class Person {
   

    private String name;
    private int age;

	//无参构造器
    public Person() {
   
    }
	//有参构造器:一旦定义了有参构造,无参就必须显示定义
    public Person(String name, int age) {
   
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
   
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    public static void main(String[] args) {
   
        Person[] people = new Person[4];
        people[0] = new Person("yt", 20);
        people[1] = new Person("wx", 21);
        people[2] = new Person("wx", 20);
        people[3] = new Person("wx", 23);
        Person persons = new Person();
        System.out.println(Arrays.toString(people));
    }
}

创建对象的内存分析

对象是通过引用操作的: 栈—>堆

例子:

public class Pet {
   
    String name;
    int age;
    
    public void shout(){
   
        System.out.println("叫了一声");
    }
}
public class Application {
   
    public static void main(String[] args) {
   
        Pet dog = new Pet();
        dog.name = "旺财";
        dog.age = 3;
        dog.shout();
        System.out.println(dog.name);
        System.out.println(dog.age);
        Pet cat = new Pet();
    }
}

Java 面向对象

封装

该露的露,该藏的藏

  • 我们程序设计要追求 “高内聚,低耦合” 。高内緊就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。

封装(数据的隐藏)

  • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。

记住这句话就够了: 属性私有,get/set

例子:

public class Person {
   

    private String name;
    private int age;


    public Person() {
   
    }

    public Person(String name, int age) {
   
        this.name = name;
        this.age = 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;
    }
}

继承

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。

extands的意思是“”扩展”。子类是父类的扩展。

Java中类只有单继承,没有多继承!(接口可以多继承)

继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。

继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字 extends来表示。

子类和父类之间,从意义上讲应该具有”isa”的关系。

final修饰的类无法继承。

例子:

public class Person {
   

    private String name;
    private int age;


    public Person() {
   
    }

    public Person(String name, int age) {
   
        this.name = name;
        this.age = age;
    }

}
public class Student extends Person {
   
    public Student(){
   
        //隐藏代码:调用父类的无参构造 super();
        //调用父类的构造器,必须要在子类构造器的第一行
        //如果父类没有无参构造器,子类无法调用父类的无参构造器,但是可以调用父类的有参构造器,实现无参构造器
    }

}
public class Teacher extends Person{
   

}

子类继承了父类,就会拥有父类的全部方法。

稀有的属性和方法无法被继承。

object类

  • 在Java中,所有的类都默认直接或间接继承Object类。

super

  • super调用父类的构造方法,必须在构造方法的第一行。
  • super必须只能出现在子类的方法或者构造方法中。
  • super和this不能同时调用构造方法。

方法重写

  • 重写都是方法的重写,和属性无关。
  • 子类重写父类的方法
    • 方法名必须相同。
    • 参数列表必须相同。
    • 修饰符:范围可以扩大,不可以缩小, public>protected>default>private。
    • 抛出异常范围:可以缩小,不可以扩大。
  • 静态方法:方法的调用只和左边,定义的数据类型有关。
  • 非静态方法:重写。
  • 为什么要重写?
    • 父类功能,子类不一定需要,或者不一定满足。

例子:

public class B {
   
    public  void test(){
   
        System.out.println("B=>test");
    }
}
public class A extends B{
   
    @Override
    public  void test(){
   
        System.out.println("A=>test");
    }
}
public class Application {
   
    public static void main(String[] args) {
   
       A a=new A();
       a.test();
       //父类的引用指向了子类
        B b=new A();//子类重写了父类的方法
        b.test();
    }
}

A=>test
A=>test

多态

即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。

动态编译: 类型可扩展。

多态存在的条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

例子:

public class Student extends Person {
   

}
public class Application {
   
    public static void main(String[] args) {
   
        //一个对象的实际类型是确定的
        //new Student();
        //new Person();
        //可以指向的引用类型就不确定了:父类的引用指向子类
        
        //Student 能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        //Person 父类型,可以指向子类,但是不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();
        //对象能执行那些方法,主要看对象左边的数据类型,和右边的new关系不大
    }
}

注意:

  • 多态是方法的多态,属性没有多态性。
  • 父类和子类,有联系,类型转换异常!ClassCastException!

instanceof (类型转换) 引用类型

例子:

public class Application {
   
    public static void main(String[] args) {
   
        //Object string
        //Object Person Teacher
        //Object Person Student
        Object object = new Student();
        System.out.println(object instanceof Student); //true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object); //true
        System.out.println(object instanceof Teacher); //false
        System.out.println(object instanceof String); //false
       	Person person = new Student();
        System.out.println(person instanceof Student); //true
        System.out.println(person instanceof Person); //true
        System.out.println(person instanceof Object); //true
        System.out.println(person instanceof Teacher); //false
        //System.out.println(person instanceof String);//编译错误
    }
}

类型之间的转换: 父 —–> 子

高—>低 强制转换

低—>高 自动转换

子类转父类 会损失自己本来的一些方法。

方便方法的调用,减少重复的代码!

static关键字

static修饰属性,需要通过类名去调用。

静态变量多用于多线程。

静态方法无法之间调用非静态方法,需要通过实例化对象进行调用,可以直接调用当前类的静态方法,或者通过类名调用其他类的静态方法。

非静态方法可以直接调用当前类的静态方法。

{
   
    //匿名代码块,创建对象的时候执行,在构造器前面
}
static{
   
    //静态代码块,类加载的时候,永久执行一次
}

静态导入包

import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Application {
   
    public static void main(String[] args) {
   
        System.out.println(random());
        System.out.println(PI);
    }
}

抽象类

abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。

抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。

抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。

抽象方法,只有方法的声明没有方法的实现,它是用来让子类实现的。

子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。

例子:

public  abstract class B {
   
    public  void test(){
   
    }
}

public class A extends B{
   

    @Override
    public  void test(){
   
        System.out.println("A=>test");
    }
}

接口

普通类: 只有具体实现

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

接口: 只有规范!自己无法写方法!约束和实现分离:面向接口编程

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

声明类的关键字是 class,声明接口的关键字是 interface

例子:

public interface UserServiceDao {
   
    /** * @param user * 登录 * @return boolean */
    public boolean login(User user);

    /** * @param user * 注册 * @return boolean */
    public boolean register(User user);

    /** * @param user * 更新 * @return */
    public void update(User user);
}

方法修饰 public abstract

属性修饰 public static final

接口不能实例化,没有构造方法。

implements可以实现多个接口。

内部类

内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。

  1. 成员内部类
  2. 静态内部类
  3. 局部內部类
  4. 匿名内部类
  5. Lambda表达式

成员内部类

例子:

public class Outer {
   
    private int id=10;
    public void out(){
   
        System.out.println("这是外部类方法");
    }
    class Inner{
   
        public void in(){
   
            System.out.println("这是内部类方法");
        }
        //获得外部类的私有属性
        public void getID(){
   
            System.out.println(id);
        }
    }
}

public class Application {
   
    public static void main(String[] args) {
   
        Outer outer = new Outer();
        //通过外部类来实现内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getID();
    }
}

静态内部类

例子:

public  class Outer {
   
    private int id=10;
    public void out(){
   
        System.out.println("这是外部类方法");
    }
    static class Inner{
   
        public void in(){
   
            System.out.println("这是内部类方法");
        }

    }
}

局部内部类

例子:

public  class Outer {
   
    private int id=10;
    public void out(){
   
        System.out.println("这是外部类方法");
    }
    public void method(){
   
        class Inner{
   
            public void in(){
   
                System.out.println("这是内部类方法");
            }

        }
    }
}

匿名内部类

例子:

public class Application {
   
    public static void main(String[] args) {
   
      	//没有名字初始化类,不用将实例保存到变量中
        new Apple().eat();
    }
}
class Apple{
   
    public void eat(){
   
        System.out.println("1");
    }
}

Lambda表达式

Lambda表达式(也称为闭包),Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中),或者把代码看成数据。一个Lambda可以由用逗号分隔的参数列表、–>符号与函数体三部分表示。

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

语法:

(parameters) -> expression
或
(parameters) ->{
    statements; }

以下是lambda表达式的重要特征:

  • 可选类型声明: 不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号: 一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号: 如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字: 如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

Lambda 表达式实例

// 1. 不需要参数,返回值为 5 
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值 
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值 
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和 
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) 
(String s) -> System.out.print(s)

例子:

public class Java8Tester {
   
   public static void main(String args[]){
   
      Java8Tester tester = new Java8Tester();
        
      // 类型声明
      MathOperation addition = (int a, int b) -> a + b;
        
      // 不用类型声明
      MathOperation subtraction = (a, b) -> a - b;
        
      // 大括号中的返回语句
      MathOperation multiplication = (int a, int b) -> {
    return a * b; };
        
      // 没有大括号及返回语句
      MathOperation division = (int a, int b) -> a / b;
        
      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));
        
      // 不用括号
      GreetingService greetService1 = message ->
      System.out.println("Hello " + message);
        
      // 用括号
      GreetingService greetService2 = (message) ->
      System.out.println("Hello " + message);
        
      greetService1.sayMessage("Runoob");
      greetService2.sayMessage("Google");
   }
    
   interface MathOperation {
   
      int operation(int a, int b);
   }
    
   interface GreetingService {
   
      void sayMessage(String message);
   }
    
   private int operate(int a, int b, MathOperation mathOperation){
   
      return mathOperation.operation(a, b);
   }
}

输出结果为:

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Runoob
Hello Google

使用 Lambda 表达式需要注意以下两点:

  • Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
  • Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。

变量作用域

lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

例子:

public class Java8Tester {
   
 
   final static String salutation = "Hello! ";
   
   public static void main(String args[]){
   
      GreetingService greetService1 = message -> 
      System.out.println(salutation + message);
      greetService1.sayMessage("Runoob");
   }
    
   interface GreetingService {
   
      void sayMessage(String message);
   }
}

输出结果为:

Hello! Runoob

我们也可以直接在 lambda 表达式中访问外层的局部变量:

例子:

public class Java8Tester {
   
    public static void main(String args[]) {
   
        final int num = 1;
        Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
        s.convert(2);  // 输出结果为 3
    }
 
    public interface Converter<T1, T2> {
   
        void convert(int i);
    }
}

lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

int num = 1;  
Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num));
s.convert(2);
num = 5;  
//报错信息:Local variable num defined in an enclosing scope must be final or effectively 
 final

在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

String first = "";  
Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length());  //编译会出错 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114432.html原文链接:https://javaforall.net

(0)
上一篇 2021年10月6日 下午11:00
下一篇 2021年10月7日 上午6:00


相关推荐

  • 使用java在项目完成手机短信登录

    手机号登录在现在的项目中用的场景非常多,实现起来也不难,今天我们就一起来通过演示实现登录过程。&lt;1&gt;首先需要注册个第三方的账户,比如秒嘀科技等,然后拿到三个参数值:QUERAY_PATHACCOUNT_SIDAUTH_TOKEN&lt;2&gt;编写获取验证码类getMessage.javaprivatestaticfinalStringQUER…

    2022年4月17日
    47
  • ${sessionScope.user}的使用方法

    EL 全名为ExpressionLanguageEL 语法很简单,它最大的特点就是使用上很方便。接下来介绍EL主要的语法结构:${sessionScope.user.sex}所有EL都是以${为起始、以}为结尾的。上述EL范例的意思是:从Session的范围中,取得用户的性别。假若依照之前JSPScriptlet的写法如下:Useruser=(Us

    2022年4月4日
    60
  • 五种大数据框架你必须要知道

    五种大数据框架你必须要知道学习大数据不可不知的五种大数据框架 码笔记分享大数据框架 Hadoop Storm Samza Spark 和 Flink 五种大数据框架详解 一 Hadoop 大数据框架 Hadoop 大数据框架 第一映入眼帘的就是这枚大象 Hadoop Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构 它是目前应用最广泛的大数据工具 Hadoop 拥有容错率和极低的硬件价格 H

    2026年3月16日
    2
  • 03-wtm项目模型创建

    03-wtm项目模型创建一对多 多对多 支持密码类型

    2026年3月17日
    2
  • 单臂路由的实现过程

    单臂路由的实现过程目录一 vlan 跨交换机的传输过程二 VLAN 间通信使用的技术三 vlan 的标识四 单臂路由实现思路总结一 vlan 跨交换机的传输过程 PC 机经过发送方交换机某个接口发送数据 此时交换机会对应 vlan 信息表 给经过某接口的数据打上对应的标签 打上对应标签的数据经由 trunk 主干 链路验证这个 vlanid 是不是 trunk 链路的白名单范围内 若是在白名单范围内 无条件放行 若不在白名单范围内 则该流量不予通过 当打了标签的额数据到达接收方交换机后 接收方交换机会解开这个数据

    2026年3月17日
    1
  • vmware15最新激活码2021_在线激活

    (vmware15最新激活码2021)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月22日
    81

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号