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());  //编译会出错 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 通俗易懂的Mybatis工作原理[通俗易懂]

    作为半自动的ORM框架,Mybatis被越来越多的企业接受。搞清楚它的工作原理以及底层实现,对于开发者可事半功倍。很多文章都是使用大批量的源码流程去分析原理。对于有源码阅读功底的开发者,也许还能招架住,但还是不直观。我以前的很多文章都是这么做的,后来有朋友私信建议说,这些文章类似于个人笔记,只能自己阅读,不利于分享,所以,本文将尝试采用通俗易懂的白话文带领大家认识一下Mybatis的工作原理。(PS:大家可以设想,如果自己在开发Mybatis,该如何设计好Mybatis的功能呢?)一...

  • powerDesigner生成HTML报表

    powerDesigner生成HTML报表报告-GenerateReport

  • 20道web前端面试总结「建议收藏」

    本文总结了20道前端面试题,包括布局原理,盒子模型,ajax异步请求,事件等基础题,有需要的小伙伴可以参考学习。

  • 苹果绕id完美重启_iphone重启要输入id密码

    苹果绕id完美重启_iphone重启要输入id密码朋友捡到一个iphone6,已经很老的版本了,并且拆修过,手机没有关机等着人家来要,但是第二天就变成iphone已停用,估计别人也是觉得不值得找回了吧。手机就相当于是砖头了,然后交给我,让我尝试激活成功教程试试。在B站看了几个视频,发现网上有很多激活成功教程的软件,但是都是不能当电话用了,只能当做小pad用了,有的软件激活成功教程后不能关机重启,因为一旦关机重启就又锁上了,有的软件激活成功教程后不能登录iCloud,应该就是说不能登录AppID,不能登录应该就不能通过AppStore下载软件了吧。有的软件是通过删除基带的方式,这种方式据

  • 学习双拼必看(最全教程):双拼输入法的心得以及快速入门办法

    学习双拼必看(最全教程):双拼输入法的心得以及快速入门办法1.简单介绍一下双拼2.总共18种双拼方案3.15种双拼方案的具体映射4.顺便提一下双拼口诀的事情5.总结不同平台选择的方案双拼(也称双打)是一种建立在拼音输入法基础上的输入方法,可视为全拼的一种改进,它通过将汉语拼音中每个含多个字母的声母或韵母各自映射到某个按键上,使得每个音都可以用两个按键打出,极大地提高了拼音输入法的输入速度。这种声母或韵母到按键的对应表通常称之为双…

  • 初探sendfile「建议收藏」

    初探sendfile「建议收藏」很早就知道sendfile这个专门用来传输大文件的函数,也称为零拷贝,但一直没测试过,今天用了宿舍的网和小组内的网测试了下,发现结果和我预想的不一样。为什么效率高,网上说的也很多了,看下man手册中的内容sendfile()copiesdatabetweenonefiledescriptorandanother.Becausethiscopyingisdo

发表回复

您的电子邮箱地址不会被公开。

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