java面向对象编程基础

类与方法

什么是面向对象?

javac -encoding UTF-8 temperature.java

chcp 936 gbk
chcp 65001 utf-8

面向机器语言
针对不同的机器01011100这样的机器语言指令

面向过程语言

c语言
由过程块和函数块组成
每个块的目的是完成某个任务

面向对象语言

基于对象的编程
c++
java
python
更加符合人的思维模式
特性:抽象封装继承多态

类与对象

类在使用前经过类加载、类验证、类准备、类解析、类初始化等几个阶段

加载连接初始化(加载、初始化)(jvm)
类的加载由类的加载器(通常由JVM提供,也可以通过继承ClassLoader基类创建自己的类加载器)完成,
在类的准备阶段为类为该类所有的静态成员变量分配内存

初始化后将为类的类变量分配内存空间(堆中),并指定默认初始值(先执行初始化代码或声明实例变量时指定的初始值,再执行构造器里指定的初始值
初始化后类的加载会创建一个java.lang.Class对象
在这片内存设置了成员变量的初始值

实例变量的作用域与对应实例的生存范围相同

源文件是扩展名为java的

类的实现包括两个部分
类声明和类体

class用来定义类
class abd{
//成员变量
//成员方法
//类体的内容
}
成员方法
[权限修饰符] [返回值类型]方法名([参数类型 参数名])[throws 异常类型]{
//方法体
return 返回值;
}
权限:private(同一个类)/(default包访问权限)/public/protected(子类中)
封装
外部类由两个权限:public和default
如果定义了public 的类,源文件名必须和public修饰的类的类名相同
访问控制符
Private int abc;
public void setAbc(int abc);
javaBean一个封装良好的类

方法的定义必须在某个类

//方法的定义必须在类中,定义方法的时候没有权限限定的话默认只能类中访问

public class Bird{
string wing;
string claw;
string beal;
string feather;
public void showGoods{
System.out.println(“库存商品信息”);
}
}

public class BIrd{

}
方法如果有返回值就要return该类型数据
public float demo{
System.out.println(“sssss”);
return 1.2;
}
成员方法参数
值参数、引用参数、不定长参数

值参数:将实际参数值的副本传入方法内
实际参数不受影响

如果传入的是对象的引用地址的话可以直接修改变量的值
形参个数可变的方法
形参个数
成员变量

没有赋值的话由默认值
整型byte,short、int、long都是默认值为零
float,double默认值为0.0
char 默认值为空格字符
boolean默认为false
引用类型String默认值为null

成员变量和局部变量
系统不会为局部变量赋默认值
局部变量必须通过初始化才能使用:方法和代码块局部变量指定初始值才能访问
栈中的变量不需要垃圾回收机制处理,往往随着方法和代码块的运行结束而结束
例子
public class temperature{
public static void main(String[]args){
temperature book = new temperature();//创建本类对象
int shelf = 30;
int box = 40;
System.out.println(“把书架上的书全部放进箱子后,箱子里一共有”
+book.add(shelf,box)+“本书\n”+“明细如下:书架上”+shelf+“本书,箱子里原有”+box+“本书”);

}
private int add(int shelf,int box){
	box = box+shelf;
	return box;
}

}

public class temperature{
public static void main(String []args){
temperature rate = new temperature();
double[] denomination = {1,10,100};
System.out.print(“美元:”);
for(int i=0;i<denomination.length;i++){
System.out.print(denomination[i]+“美元 “);
}
rate.change(denomination);
System.out.print(”\n人民币”);
for(int j=0;j<denomination.length;j++){
System.out.print(denomination[j]+"元 ");
}
}
public void change(double[] i){
for(int j=0;j<i.length;j++){
i[j] = i[j]*6.903;
}
}
}

不定长参数
有若干个相同类型的参数,
权限修饰符 返回值类型 方法名(参数类型… 参数名)
public int jia(int …abd){
}
参数类型与参数名之间是三个点、

使用方法可以将变量看作是数组使用
如下实例
可变形参的方法
public class Varaus{
public static void test(int a,String…books){//方法
for(String temp:books){
System.out.println(temp);
}
System,out,println(a);
}
public static void main(String[] args){
test(5,“你好哇”,“你今天真好看”);
}
}
数组的方法
public class Varaus{
public static void test(int a,String[] books){//方法
for(String temp:books){
System.out.println(temp);
}
System,out,println(a);
}
public static void main(String[] args){
test(5,“你好哇”,new String[]{“你今天真好看”,“你好哇”});
}
}

不定长形参的方式更加简洁
但是不定长形参只能在形参列表的最后,且只能有一个

如果有这种情况
public void test(String msg){}
public void test(String… books){}
当test(“aa”)的时候系统会调用第一个
当test(new String[]{“aa”})的时候系统会调用第二个

构造方法

class temperature{
public temperature(){
}
}
构造方法的名字要和本类同名
主要作用是完成对象的初始化操作
它能把定义对象的参数传给对象成员。

成员变量的默认值直接在初始化的时候赋值就可以了

注意创建类和成员变量的时候成员的名字首字母大写更加可读

如果类中没有明确定义构造方法,则编译器会自动创建一个不带参数的默认构造方法
和c++相同
没有的话就默认创建一个无参的

构造方法支持重载
静态初始化块再构造执行之前就运行了
修饰符public final abstract
构造器返回值类型总是当前的类(隐式地),不用定义返回值的类型
new的时候返回该类的实例

通过new来调用构造器

构造器、成员变量、方法

public class temperature{
public temperature(){

}
public void borrow(String name){
	System.out.println("请前往借阅登记处领取"+name+"。");
}
public static void main(String []args){
	temperature book = new temperature();
	book.borrow("《战争与和平》");
}

}

public class temperature{
String bookname;
public temperature(String name){
bookname = name;

}
public void borrow(){
	System.out.println("请在借阅处yiyi登记"+bookname);
}

public static void main(String []args){
	temperature book = new temperature("《战争与和平》");
	book.borrow();
}

}
特殊的构造方法
public class Apple{
public String name;
public String color;
public double weight;
public Apple(){}
public Apple(String name,String color){
this.name = name;
this.color = color;
}
public Apple(String name,String color,double weight){
this(name,color);//特殊之处复用了代码
this.weight = weight;
}
string 数组引用型变量
对象里的引用型变量存放的是该变量的地址
就是c中的指针包装成的引用方法
对象创建成功保存在堆之中
只能通过栈中的引用来操作成员
堆中的对象可以有多个引用指向同一个对象
没有任何引用指向的时候就是到了java的垃圾回收机制清理它的时候了
希望通知java的回收机制回收某个对象的时候只需要将这些引用变量赋值为null

调用成员变量的方法

this 关键字
1.局部变量的参数优先于方法中的成员变量的使用
局部变量会覆盖成员变量
2.Java规定用this指针表示本类对象的使用
隐式地用于引用对象的成员变量和方法
this关键字引用的是本类对象
this关键字可以作为方法的返回值
return this
3.this可以调用构造函数
static关键字
static 静态变量、静态常量、静态方法

static修饰的成员只能访问static 成员

1.静态变量
共享的变量

2.静态方法
无法创建类的对象的还想调用类的方法就可以使用静态方法
类名.静态方法

3.静态方法
使用静态方法表示水池中的水量及其变化

静态的弊端:
扩大了变量的生存时间,更大的内存开销
扩大了变量的作用域,不利于程序的内聚性

能用代码块局部变量的坚决不要用方法局部变量

public class temperature{
public static int water=0;
public static void outlet(){
if(water>=2){
water = water-2;
}else{
water=0;
}
}
public static void inlet(){
water = water + 3;
}
public static void main(String[] args){
System.out.println(“水池的水量:”+temperature.water);
System.out.println(“水池注水两次。”);
temperature.inlet();
temperature.inlet();
System.out.println(“水池的水量:”+temperature.water);
System.out.println(“水池放一次。”);
temperature.outlet();
System.out.println(“水池的水量:”+temperature.water);
}
}
静态成员变量初始化直接在类里面

没有使用static修饰的成员变量和方法必须用对象来调用
public class dog{
public void jump{
System.out.println(“执行jump方法中”);
}
public void run(){
this.jump();//this可以省略
System.out.println(“正在执行run方法”);
}
}
public class DogTest{
public static void main(String [] args){
Dog dog = new Dog();
dog.run();
}
}
static修饰的方法不能用this引用

2.静态代码块

public class temperature{
static String name;
static {
System.out.println(name+“静态代码块”);
}
{
System.out.println(name+“非静态代码块”);
}
public temperature(String a){
name = a;
System.out.println(name+“构造方法”);
}
public void method(){
System.out.println(name+“成员方法”);
}
public static void main(String []args){
temperature s1;
temperature s2 = new temperature(“s2”);
temperature s3 = new temperature(“s3”);
s3.method();
}
}
相同类型的初始化块先定义的先执行
初始化块的修饰符只能是static
在构造器之前执行
再javac命令编译后java类中的初始化块会消失,初始化块中的代码会被还原到每个构造器中
静态初始化块不能对实例变量进行初始化处理(静态变量不能访问非静态变量)

类的初始化块最先执行最顶层的父类的静态初始化块,再到执行当前类的静态初始化块
类初始化成功后该类就存在与虚拟机中,无需二次初始化
对象初始化阶段,最先执行最顶层父类的初始化块,最顶层父类的构造器,直到当前类的初始化块,当前类的构造器

声明的时候就已经运行了静态代码块了
之后不再执行静态代码块
非静态代码块再执行
构造函数后再只执行一次
在这里插入图片描述

类的主方法
public static void main(String[] args)
{
}
static类的主方法是静态的,如果要直接调用其他方法的话都要是静态的才行
void 主方法没有返回值 void
主方法的形参为数组args[0]到args[n]
可以用args.length获取参数的个数

方法不能独立存在
要么属于类要么属于对象
方法不能像函数那样独立执行必须通过类或对象调用
6

模块设计追求低耦合,高内聚
高内聚(将数据隐藏)
低耦合(暴露少量的方法)

package、import、import static
-d命令自动生成文件夹 0.1
要在文件前面添加package 包名
javac -d 类名.java
静态成员的导入需要静态方法
import static

源文件的结构:

package
import |import static
public class|interface|enum
接口定义枚举定义
java的常用包
java.lang
java.util
java.net
java.io
java.text
java.sql
java.swing
java.awt
包解决的命名冲突的问题

继承与多态

package语句:源文件定义的所有类都属于这个包
提供了类的多层命名空间,用于解决类的命名冲突,类文件管理

继承关键字

1.extends
继承分为单继承和多重继承
一个类只能有一个直接父类

public class A{}
public class B extends A{}
public class C extends C{}
2.implements
可以实现多个接口
public interface if2{
public void method2();
}
public interface if1{
public void method1();
}
public class if3 implements if1, if2{}

3.super和this
super 引用当前对象的父类
this指向当前类的引用
class Mother{
void method(){
System.out.println(“这是父类的方法”);
}
}
class Son extends Mother{
void method(){System.out.println(“这是子类的方法”);}

void diff_method(){
this.method();
super.method();
}
}
public class temperature{
public static void main(String[] args){
Mother father = new Mother();
father.method();
Son son = new Son();
son.diff_method();
}
}
super和this一样都不能在static修饰的方法中
static 修饰的是类

在这里插入图片描述

class Base{
public double size;
public String name;
pulic Base (double size,String name){
this.size = size;
this.name = name;
}
}
public class Sub extends Base{
public String color;
public Sub(double size,String name,String color){
super(size,name);//必须在第一行
this.color = color;
}
public static void main(String []args){
Sub s = new Sub(5.6,“测试对象”,“红色”);
System.out.pritnln(s.size+"–"+s.name+"–"+s.color);
}
}
父类构造器总会在子类构造器之前执行
创建任何java对象的时候最先执行的总是java.lang.Object的构造器

4.final
final功能是将类定义为不可继承的
修饰的方法不能被子类重写

继承的特性

  1. 子类不继承父类的private属性和方法
  2. 子类可以对父类进行扩展,拥有自己的属性和方法
  3. 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类
    的构造器带有参数,则必须在子类的构造器中显式地通过super关键字调用父类的构造器并配以适
    当的参数列表
  4. 如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会
    自动调用父类的无参构造器。

重写的方法的类型要一致
子类覆盖了父类的方法之后
可以用super方法或着父类类名作为调用者调用覆盖的方法
如果父类方法具有private访问权限而子类有同名的。则只是重新定义了一个方法
重载:参数不同
重写:参数相同
系统查找变量顺序:
1.局部变量
2.当前类成员变量
3.父类成员变量

继承和组合
继承破坏了封装性
为了保证父类的封装性
父类的成员变量都设置为private
还有辅助方法也设置为private
如果父类的方法必须被外部类调用,必须用public修饰
不希望子类重写该方法,就可以使用final修饰符

多态

编译时多态,运行时多态

多态的转型(向上和向下)
回顾:基本类型只能在数值之间转换
数值类型和布尔类型之间不能进行类型转换
引用类型之间的转换只能在具有继承关系的两个类型之间进行

引用变量访问包含的实例变量的时候。系统总是访问编译时所定义的类型,而不是运行时的类型
具多态性的是方法
对象的实例变量不具备多态性

向上转型
父类类型 变量名=new 子类类型()
向下转型
子类类型 变量名=(子类类型) 父类类型的变量;
abstract class Animal{
abstract void eat();
}//抽象类
class Cat extends Animal{
public void eat(){
System.out.println(“吃鱼”)//重写父类的方法
}
public void work(){
System.out.println(“抓老鼠”);
}
}
class Dog extends Animal{
public void eat(){
System.out.println(“吃骨头”);}
public void work(){
System.out.println(“看家”);
}
}

public class temperature{
public static void main(String []args){
show(new Cat());
show(new Dog());

}
public static void show(Animal a){/向上转型只想要用父类的功能的时候
	a.eat();
	if(a instanceof Cat){//判断是否为一个类的实例
		Cat c = (Cat)a;//向下转型 要强制转换类型为子类的时候,调用子类的功能
		c.work();
	}else if(a instanceof Dog){
		Dog c = (Dog)a;
		c.work();
	}
}

}
进行类型转换之前应该使用instanceof 运算符判断是否可以成功转换
instanceof要么是同一类要么是有继承关系,不然就会编译出错
利用组合实现复用
组合内存开销和继承的差不多
采用组合的方式只是多了一个引用变量来引用被嵌入的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值