JavaSE面向对象编程

目录

什么是面向对象编程?

类的成员

成员之一:属性。

成员之二:方法(动态)

方法的重载(Overload)

构造器(构造方法)

面向对象三大特征:封装,继承,多态

1.封装

this关键字

2.继承(Inherit)

方法的重写(override)

super关键字

3.多态(Polymorphism)

toString()方法

static(静态的)

关键字final

抽象类(Abstract)

接口(interface)

匿名内部类


什么是面向对象编程?

面向对象编程(Object Oriented Programming,简称OOP)其实就是将所有的程序一个一个地分成子程序,这些子程序有各自的作用,然后将其组合起来,在主函数里调用这些子程序,举个例子,人将大象关进冰箱需要几步?三步。1.人打开冰箱。2.人将大象放进去。3.人关闭冰箱。因此我们可以将这件事拆分成3个对象:人、大象、冰箱。人的方法可以是:1.打开。2.放入。3.关闭。大象的方法可以是:1.进入。冰箱的方法可以是:1.接受(大象)。

这样大家可以看出来什么是面向对象编程了吧,他的优点是:可以隐藏一些不需要的细节,提高程序的复用性降低程序之间的耦合度,并且安全性得到了保障。

如何定义一个类呢?这里有个公式是:​ 权限修饰符 class 类名{}  。在一个文件中可以定义多个类,但是只能有一个public类。(潜规则:一个文件一个类)并且public修饰的类必须与文件名同名。

类的成员

类的成员分为两种,一种是属性,一种是方法。当然,这些成员还能再细分成各种分支。

成员之一:属性。

属性=成员变量。属性存储在堆内存中 局部变量存储在栈内存中,成员变量(属性)都有默认值 :byte short int long是0,float double是0.0,char是空格,boolean是false,引用数据类型是null

公式:权限修饰符 数据类型 变量名 [= 值];

public 公共的,private 私有的(只能类的内部使用)

成员之二:方法(动态)

有返回值公式:权限修饰符 返回值类型 方法名(){语句.... return 返回值;}

无返回方法公式:权限修饰符 void 方法名(){语句.... [return;]}

return 方法的结束 可以return 常量 return 变量 return 表达式 ​ 返回值类型如果是引用数据类型,那么return时返回的是这个类型的地址 ​ 方法内不能再定义方法,方法之间可以相互调用

创建和使用:类名 对象名 = new 类名(); 对象.属性 对象.方法

设计方法的参数叫形参 使用方法的参数叫实参

匿名对象只能使用一次,要么就当做参数传递例如:

new Person().name = "abc"
System.out.println(new Person().name)

输出:null(引用数据类型的默认值)

如果说程序占用内存较高,那可以使对象置空,即变量 = null

方法链式调用:对象.方法.方法 相当于方法中调用方法,后面的方法取决于前面方法的返回值,有返回值才能调用。

方法的重载(Overload)

在同一个类中,存在同名方法,参数列表不同就是重载(一定要是同名的)。

重载与变量名和返回值无关,与数据类型有关

Java里方法的参数传递只有一种:值传递。基本数据类型:将实际参数的副本传入方法中,参数本身不受影响。引用数据类型:将对象的地址传入或传出方法。例如:

public class TestTransfer {
    public static void swap(int a , int b){
        int tmp = a;
        a = b;
        b = tmp;
        System.out.println("swap方法里,a的值是"  + a + ";b的值是" + b);
    }
    public static void main(String[] args) {
        int a = 6;
        int b = 9;
        swap(a , b);
        System.out.println("交换结束后,变量a的值是"  + a + ";变量b的值是" + b);
    }
}

swap方法里,a的值是9;b的值是6 交换结束后,变量a的值是6;变量b的值是9

在方法中new一个新的对象,新的对象的值与主函数中的值不相干

重载属于多态的一种体现

如果想要传很多个数,参数中可以用(int ... a),这个相当于一个数组,可以直接传参数,没必要传数组进去了,不过只能有一个多参,并且多参必须放在参数列表的最后面。

构造器(构造方法)

一个类中,如果没有显示定义构造器,那么系统会默认提供一个无参构造器(编译时检查,如果没有就提供)

一旦显示定义了构造器,那么系统默认的无参就没有了,所以要重新自己设置一个无参的构造器

用来初始化,不能有返回值(return)

公式:权限修饰符 类名(参数列表...){初始化语句...}

构造器也可以进行重载,也可以调用普通方法

面向对象三大特征:封装,继承,多态

1.封装

封装的作用:限制对属性的不合理操作(属性私有化),提供公共的getxxx和setxxx方法,便于修改,增强代码的可维护性,隐藏一个类中不需要对外公布的细节

潜规则:属性私有公共的get set方法(是为属性服务的),再设计其他的方法

方法也可以封装,例如:

    //玩play:参数String host,返回值 String “飞盘”, 打印:小狗与主人host玩的很开心
    public String play(String host){
        System.out.println("小狗与主人"+host+"玩的很开心");
        bark();
        return "飞盘";
    }
    //叫bark:打印:小狗喜欢汪汪叫,封装此方法,玩play()的时候才bark()
    private void bark(){
        System.out.println("小狗喜欢汪汪叫");
    }

其实就是将bark方法私有化,只能通过类中的方法来调用。

this关键字

this代表当前类的对象 对象.属性 对象.方法

在构造器和普通方法中都可以用this

this()只能出现在构造器中,且必须出现在构造器的首行,作用是调用本类中的无参构造器,如果想要调其他有参构造器,那可以在括号里加(数据类型 变量)。 当形参与成员变量重名时,如果在方法内部需要使用成员变量,必须添加this来表明该变量时类成员

2.继承(Inherit)

子类继承了父类中的属性和方法(私有的除外),是为了让子类更加关注子类独有的业务

extends 扩展 子类扩展了父类(超类,基类)

一个子类只能有一个父类(java中叫单继承),反过来说,一个父类可以有多个子类,子类和子类之间没有任何关系,子类可以继续有子类(层次无限制,保证单继承就行了)

继承的出现让类与类之间产生了关系,提供了多态的前提

类和类之间继承关系:1.子类 extends 父类 2.子类构造器在调用父类构造器(默认情况下,无参调无参,有参调有参)

当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一行

如果子类构造中既未显式调用父类或本类的构造,且父类中又没有无参的构造,则编译出错

方法的重写(override)

父类方法已经无法满足子类需要,就可以对父类的方法进行升级改造。

重写:返回值类型 方法名 参数列表必须相同子类的权限修饰符必须要大于等于父类

重写后,此时父类方法已经不可见,调用的都是子类中的方法,重写和被重写的方法须同时为static的,或同时为非static的子类方法抛出的异常不能大于父类被重写方法的异常

super关键字

在Java类中使用super来调用父类中的指定操作

super没有类对象的概念  向上(父类)找

super.父类(不限于直接父类)的属性和方法

super() 相当于使用父类的构造器。必须出现在构造器首行

super()和this()只能出现一个

如果父类有有参构造器则子类中有参构造器的首行如果为super(),则自动调用父类中的构造器内容

访问权限:

同一个包中,下面三个修饰的无论是在类内部还是类外部都可以用

修饰符类内部同一个包子类任何地方
privateYes
defaultYesYes
protectedYesYesYes
publicYesYesYesYes

重写代码举例:

class Parent {
	public void method1() {
        System.out.println("父类方法")
    }
}

class Child extends Parent {
	private void method1() {
        System.out.println("子类方法")
    }
//非法,子类中的method1()的访问权限private比被覆盖方法的访问权限public弱
}

public class UseBoth {
	public static void main(String[] args) {
		Parent p1 = new Parent();
		Child p2 = new Child();
		p1.method1();
		p2.method1();
	}
}

输出:异常(因为子类中的method1()的访问权限private比被覆盖方法的访问权限public弱)

若正确(private改成public),则输出:父类方法 子类方法

3.多态(Polymorphism)

多态是建立在继承的基础上的

属性不具有多态性,只有方法具有多态性

基本上都是定义父类然后传子类

公式:父类 对象名 = new 子类构造器();

对象的多态性,都是用于设计参数,设计参数时规定了传入参数的一个范围

等号左边:编译时类型(写代码的过程)

等号右边:运行时类型(运行代码实际产生的对象)

方法的调用是在运行时确定的

运行时调用子类中重写的方法,写代码时调用父类的方法

当编译时类型与运行时类型不一致时,就发生多态(左边为父类,右边为子类)

举例:

public class Animal {

    public void eat(){
        System.out.println("吃饭");
    }
}
public class Dog extends Animal{
    public void eat(){
        System.out.println("狗吃骨头");
    }

    public void sleep(){
        System.out.println("狗睡觉");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal a = new Dog();

        a.eat();

        ((Dog) a).sleep();
    }
}

如果想要调用子类的方法,那就需要对父类进行强制类型转换(向下转型)

基本数据类型有大小之分(byte 2 字节,int 4 字节等),引用数据类型也有大小之分(父类大,子类小)

多态属于自动转换类型(向上转型)

关键字 instanceof(a instanceof B)

主要用于判断是否为右边的类型,并且返回boolean类型的数据,只有判断了才能向下转型。

public class Simple {
    public static void main(String[] args) {
        Simple simple = new Simple();
        System.out.println(simple instanceof Simple);
    }
}

输出为True

要求x所属的类与类A必须是子类和父类的关系,否则编译错误。

如果a属于类B的子类A,a instanceof B值也为true

引用类型转换分为强制转换和自动转换。自动转换中小的数据类型可以自动转换成大的数据类型,强制转换可以把大的数据类型强制转换(casting)成小的数据类型,但是需要使用instanceof

无继承关系的引用类型间的转换是非法的

在造型前可以使用instanceof操作符测试一个对象的类型

Object是所有引用数据类型的父类

Object类中的主要方法:

No,方法名称类型描述
1

public Object()

构造

构造方法

2

public boolean equals(Object obj)

普通

对象比较

3

public int hashCode()

普通

取得Hash

4

public String toString()

普通

对象打印时调用

==(比较的是堆内存中的值) 比较基本数据类型是比较值,比较引用数据类型是比较地址

equals() 只能比较引用数据类型,比较是否指向同一个对象 

格式:obj1.equals(obj2)

特例:当用equals()方法进行比较时,对类FileStringDate及包装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象

原因:在这些类中重写了Object类的equals()方法

堆内存中有一个字符串常量池,字符串都放在字符串常量池中,如果说里面已经有一个相同的地址,则不会再产生一个,因此两个都指向同一个地址

toString()方法

在输出引用数据类型的数据时,自动调用toString()方法

Date now=new Date();

System.out.println(“now=”+now);  相当于

System.out.println(“now=”+now.toString());  

返回值:类名+引用地址。

可以根据需要重写toString方法

包装类

除了int变成Integer、char变成Character,其他的都是将首字母大写形成包装类

将基本数据类型赋值给引用数据类型称为装箱

反之则为拆箱仅限于基本数据类型

在Integer常量池的范围是-128-127,如果不在这个常量池中,则相当于自动new一个新的,在这个范围中,他们的内存地址是一样的,因此比较两值时可以用==,如果超出这个范围,则用equals

没有小数常量池,因此Double,float没有常量池

(equalsIgnreCase(String anotherString)比较两个String类型数据,若长度相同且各个字符串相同,则返回真,反之返回假(lang包下))

static(静态的)

静态的属性被所有对象共享,内存空间中有一个静态域,其中的对象都指向静态域。

静态属性优先于对象的存在,随着类的加载优先加载到内存中

公式:类名.静态的属性(权限允许情况下)

static也可以修饰方法,也是放在静态域中,静态方法 类名.方法

静态方法不能调用普通的属性和方法,只能new一个对象才能调用属性和方法,或者可以调用静态的方法(看堆内存中的静态域中是否有对应的属性或方法)

静态方法中不能使用this和super(没有父方法)

程序结束时静态域中的方法和属性才会被回收(不会消失)

关键字final

final修饰的类不能被继承(不能有子类)

比如Integer和String都是final修饰的

final修饰的属性为常量,必须初始化(可以直接初始化,也可以通过构造器初始化),并且要大写

static和final一起修饰的静态常量必须直接进行初始化

final修饰的方法不能被重写

抽象类(Abstract)

有抽象方法的类必须是抽象类,抽象类可以没有抽象方法(不一定全是抽象方法,也可以使用普通方法,普通方法可以不用重写)

抽象方法没有方法体,也就是没有大括号

抽象类:public abstract class A;

抽象方法:abstract void method();

有抽象类必然有子类

抽象方法(只有方法的定义,没有方法的实现)

子类必须重写父类中的抽象方法

抽象类不能实例化(创建对象)

抽象类一定是父类,并且一般大类别用抽象类

不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法

举例:

abstract class A{   
       abstract void m1( );
       public void m2( ){
	    System.out.println("A类中定义的m2方法");
       }
}

class B extends A{
       void m1( ){
	     System.out.println("B类中定义的m1方法");
       }
}

public class Test{
       public static void main( String args[ ] ){
	     A a = new B( );
	     a.m1( );
	     a.m2( );
       }
}

输出:A类中定义的m2方法 B类中定义的m1方法

接口(interface)

接口其实就是相当于一个USB的插件,把它插到电脑上就可以用了

public interface 接口名{...}

接口中只有静态常量、抽象方法

接口没有构造器

定义接口的目的就是为了让实现类实现接口(面向接口编程)

声明接口 new 实现类

实现类必须重写接口中的所有方法,不想重写则可以是抽象类(加上abstract),如果实现类没有实现全部的抽象方法,那么实现类仍为抽象类,由子类继续来实现抽象方法

接口只能继承接口,并且是多继承

实现类可以先继承后实现

public class AImpl extends A implements B,C

interface Runner { public void run();}

interface Swimmer {public double swim();}

class Creator{public int eat(){…}} 

class Man extends Creator implements Runner ,Swimmer{
		public void run() {……}
		public double swim()  {……}
		public int eat() {……}
}

接口与继承关系类似,接口与实现类之间也可以存在多态性

public class Test{
	public static void main(String args[]){
		Test t = new Test();
		Man m = new Man();
		t.m1(m);
		t.m2(m);
		t.m3(m);
	}
	public String m1(Runner f) { f.run(); }
	public void  m2(Swimmer s) {s.swim();}
	public void  m3(Creator a) {a.eat();}
}

匿名内部类

匿名内部类是没有名称的内部类。

在Java中调用某个方法时,如果该方法的参数是接口类型,除了可以传接口实现类外,还可以使用实现接口的匿名内部类作为参数,在匿名内部类中直接完成方法的实现。

public class TestDemo02 {
    public static void main(String[] args) {
        People people = new People();
        people.method();
    }
}
class People{
    private String name;
    public void method(){
        //直接对这个接口中的方法进行重写并直接使用
        class Student implements behavior{
            @Override
            public void eat() {
                System.out.println("学生韩梅梅正在吃饭");
            }
        }
        Student student = new Student();
        student.eat();
 
 
        class Teacher implements behavior{
            @Override
            public void eat() {
                System.out.println("老师李华正在吃饭");
            }
        }
        Teacher teacher = new Teacher();
        teacher.eat();
    }
}
interface behavior{
    public void eat();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值