面向对象小结

it2025-04-24  16

方法

结构体(C语言)

struct tag { member-list member-list member-list ... } variable-list ; /* tag 是结构体标签。 member-list 是标准的变量定义,比如 int i; 或者 float f,或者其他有效的变量定义。 variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。 */ struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book;

Return

声明返回类型的方法中一定要出现return语句,那么没有返回类型(void)的方法中,能不能出现return语句? --Sure. You just shouldn’t be returning an actual value.

void foo() { return void(); }

方法调用

static

非静态方法属于对象,需要通过对象来调用

静态方法属于类,可以通过类/对象来调用

public class Student{ public static void say(){} } main: Student.say();

类中方法间的调用

都是nonstatic/static,可以互相直接调用

nonstatic可以调用static,反之不行

另外:在同一个class中,static method内不能直接访问到class中的nonstatic attribute.

理解:静态方法不用创建一个实例就可以直接使用,而非静态对象需要首先有一个实例

public static void a(){ //b();报错 } public void b(){ a(); }

传参

值传递和引用传递

如果参数的类型是基本数据类型,那么就是值传递。 如果参数的类型是引用数据类型,那么就是引用传递。

//值传递 public class Test{ public static void changeNum(int a){ a = 10; } public static void main(String[] args){ int a = 1; System.out.println("before: a = "+a); //1 changeNum(a); System.out.println("after: a = "+a); //1 } } //引用传递 public class Demo03 { public static void changeName(Student s){ s.name = "tom"; } public static void main(String[] args){ Student s = new Student(); System.out.println("before: name = "+s.name); //null changeName(s); System.out.println("after: name = "+s.name); //tom } } class Student{ String name; }

this

this在类中的作用

public class Student{ public Student(){ //this("tom"): call the constructor of a String parameter this("tom"); // should only be the first line of code } private String name; //this.name: the attribute "name" in Class Student public void setName(String name){ this.name = name; } public void print(){ //this.setName: Using "setName" method in Class Student //by defalut, this.setName("tom") ~= setName("tom") this.setName("tom") } } //Error,因为this("tom")不是构造器中的第一句代码. public Student(){ System.out.println("hello"); this("tom"); }

this在类中的意义

public class Student { private String name; public Student(){ System.out.println("this = "+this); } public static void main(String[] args) { Student s = new Student(); //this = com.emelia.oop.Student@15aeb7ab this指代Student System.out.println("s = "+s); //s = com.emelia.oop.Student@15aeb7ab } }

创建与初始化对象

构造器

new 实例化一个对象(本质是调用constructor)

在这里插入图片描述 添加out至目录,会生成class文件

发现被默认生成constructor

一但定义有参构造,需要显示定义无参构造(哪怕控制)没有返回值

创建对象内存分析

static:和类一起加载

无论什么对象都可以立刻调用

引用变量名:(stack)

Pet cat;Pet dog;

在heap中新生成一个对象

new Pet();

备注:基本类型(8); 其他都被称作“引用类型”

属性:字段Field 成员变量

默认初始化 数字 0 0.0char u0000boolean false引用 null

封装、继承、多态

封装

高内聚(类的内部细节自己完成,不许外部干涉)、低耦合(仅暴露少量给外部)属性私有,设置set/get方法—限制不合法的操作

继承

1.继承

子类中继承了父类中的属性和方法后,在子类中能不能直接使用这些属性和方法,是和这些属性和方法原有的修饰符(public protected default private)相关的。

public:can be directly called

private:can not be directly called

父类中的构造器是不能被子类继承的,但是子类的构造器中,会隐式的调用父类中的无参构造器(默认使用 super关键字)。

2. Object类

Every class in Java extends Object class directly or indirectly

3.Super

子类调用父类

若父类是private,不能用super…来调用

public class Student extends Person { public Student(){ // 隐藏代码:调用了父类的无参构造 // super(); 且若显式,须在the 1st line of 子类的 constructor ... } } public class Person { public Person(){ ... } }

子类中同时有有参无参constructor,第一行只能要么父类要么子类,否则冲突:(什么都不写,默认调用父类 的无参)

public class Student extends Person { private String name; public Student(){ super(); this("hello"); // 报错 ... } public Student(String name){ this.name = name; } } public class Student extends Person { private String name; public Student(){ this("hello"); super(); // 报错 ... } public Student(String name){ this.name = name; } }

子类中若要调用父类的无参,或者不显式地调用父类的有参,父类中必须要有一个无参(只有/重写了一个有参,不行,会把无参覆盖掉,所以有参要和无参同时写!):super()报错

但是可以在子类的无参里调用父类的有参super("name");

4.重写overwrite

父子类中存在,同一个class中的method只能overload

static method不能重写

(父类)静态➡️非静态 ❌

(父类)非静态➡️静态 ❌

子类可以定义与父类的静态方法同名的静态方法(但是这个不是覆盖)

//A类继承B类 A和B中都一个相同的静态方法test B a = new A(); a.test();//调用到的是B类中的静态方法test A a = new A(); a.test();//调用到的是A类中的静态方法test

可以看出静态方法的调用只和变量声明的类型相关 这个和非静态方法的重写之后的效果完全不同

私有方法不能被重写,修饰范围(public protected default private)可以被扩大,但是不能被缩小

public class Person{ private void run(){} } //编译通过,但这不是重写,只是俩个类中分别有自己的私有方法 public class Student extends Person{ private void run(){} } public class A entends B{ @Override public void test() { //默认调用父类,有内容,重写 System.out.println("...") } } 重写后,子类的return类型需要<=父类的return类型重写后,Exception,子类<=父类

多态

1.多态

Using some of the method without concerning what the exact type the object is.

属性无多态,方法有多态

有关系,父子类

存在条件:继承关系(子类没有,执行父类;子类重写,执行子类);父类引用指向子类对象 Father f = new Son()

不能重写的:

static:属于类,不属于实例final:常量private

The final situation of a program is determained only when executing, but not yet when decoding.

The actual type of an object 是确定的

new Student(); new Person();

可指向的引用类型不确定:父类的引用➡️子类

//Student: methods --- self-generated or inherit from the super class Student s1 = new Student(); //Person: methods --- ONLY its self-generated, cannot use 子类特有的 Person s2 = new Student(); //((Student)s2).eat() Object s3 = new Student();

2.Instanceof & 类型转换

instanceof

X instanceof Y

编译通过:存在父子关系

编译为true:X指向的类型和Y有父子关系

类型转换

Person obj = new Student(); //低转高,自动;子转父,可能丢失自己本来的一些方法 Student student = (Student) obj; //高转低,强制

3.static关键字

静态属性

需要很多class同时调用一个var(属性),用static修饰

public class Student{ private static int age; private double score; public static void main(String[] args) { Student s = new Student(); System.out.println(Student.age); System.out.println(s.age); System.out.println(s.score); } }

静态方法

public class Student{ private static int count; private int num; public void run(){ //非静态方法可以调用静态方法 //go(); } public static void go(){ //静态方法可以调用静态方法,动态不可 //类加载机制 } public static void main(String[] args) { new Student().run(); Student.go(); go() }

静态代码块

public class Person { { //2.一般用于赋初值 //代码块(匿名代码块) //在constructor之前,创建Person时即创建 } static{ //1. //静态代码块 //class加载即执行,永久只执行一次 } public Person(){ //3. //... } }

静态导入包

import static java.lang.Math.random; import static java.lang.Math.PI; public class Test { public static void main(String[] args) { //之前是需要Math.random()调用的 System.out.println(random()); System.out.println(PI); } }

final

class: cannot be extend

method: can be extended, but cannot be rewritten

var: become a constant

//local var public class Person{ public void print(final int a){ //编译报错,不能再次赋值,传参的时候已经赋过了 a = 1; } } //member var - non-static member var public class Person{ private final int a; } /* 只有一次机会,可以给此变量a赋值的位置: 声明的同时赋值 匿名代码块中赋值 构造器中赋值(类中出现的所有构造器都要写)*/ //member var - static member var public class Person{ private static final int a; } /* 只有一次机会,可以给此变量a赋值的位置: 声明的同时赋值 静态代码块中赋值*/ //reference var main: final Student s = new Student(); //编译通过 s.setName("tom"); s.setName("zs"); //编译报错,不能修改引用s指向的内存地址 s = new Student();

4.抽象类

abstract

抽象类的所有methods,继承它的子类需要实现!!!(除非子类也是abstract)

存在abstract method— must be declared as abstract classabstract class内部可以写普通方法 //父类 public abstract class Person { public abstract void job(); public abstract void name(); public void walk(){ } } //子类 public class Man extends Person{ @Override public void job() { } @Override public void name() { } }

abstract class: 单继承

interface:多继承

看作一种约束:

抽象类, 不能使用new关键字来创建对象,它是用来让子类继承的。 抽象方法, 只有方法的声明,没有方法的实现,它是用来让子类实现的。

思考:

存在构造器吗?–Yes

//From StackOverFlow: https://stackoverflow.com/questions/260666/can-an-abstract-class-have-a-constructor abstract class Product { int multiplyBy; public Product( int multiplyBy ) { this.multiplyBy = multiplyBy; } public int mutiply(int val) { return multiplyBy * val; } } class TimesTwo extends Product { public TimesTwo() { super(2); } } class TimesWhat extends Product { public TimesWhat(int what) { super(what); } }

The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.

Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.

NOTE: As there is no default (or no-arg) constructor in the parent abstract class, the constructor used in subclass must explicitly call the parent constructor.

存在的意义

角色:抽象所有的function,每次新建时rewrite即可,提高效率

5.Interface

约束和实现分离

大型开发:接口写好,实现

本质是契约,需要遵守

Java 23种设计模式:这 23 种设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解

《设计模式:可复用面向对象软件的基础》

public interface UserService { //定义常量,一般不会。。。 int AGE = 99; //public static final默认 void add(String name); //public abstract 默认,可以不写 void delete(String name); void edit(String name); void query(String name); } public class UserServiceImpl implements UserService, TimeService { ...//重写所有方法,可以多继承 }

6.内部类

1.成员内部类

可以调用外部类中的var

2.静态内部类

一个java文件中可以有多个class,但只有一个public class

3.局部内部类

method中定义类,再写method

4.匿名内部类

最新回复(0)