栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java面向对象

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java面向对象

什么是面向对象 一、面向对象&面向过程
  • 面向过程:
    1. 步骤明确,第一、第二步…
    2. 适合处理一些简单的问题
  • 面向对象:
    1. 分类的思维模式,先思考问题需要哪些分类,再对分类进行单独思考,最后,再对某个分类下的细节进行面向过程的处理
    2. 面向对象适合于多人协作的问题
二、OOP
  • 面向对象编程的本质:以类的方式组织代码,以对象的形式封装数据
  • 三大特性:
    1. 封装
    2. 继承
    3. 多态
  • 类是对象的模板
二、方法的调用
  1. 静态方法
    直接通过 类名.方法名 调用
//定义一个类,静态方法
public class Student{
	public static void say(){
		System.out.println("hello");
	}
}

//main方法中
Student.say();
  1. 非静态方法
    需要在main方法中实例化这个类,才能调用非静态方法;new
//定义一个类,非静态方法
public class Student{
	public void say(){
		System.out.println("hello");
	}
}


//main方法中

Student student = new Student();
student.say();

注意:静态方法无法调用非静态方法

public class Demo01{
	public static void main(String[] args){
		
	}

	//静态方法是和类一起加载的
	public static void a(){
		b(); //报错,因为b还没被实例化,该方法还不存在
	}

	//非静态方法需要实例化后才存在
	public void b(){
	}

}
  1. 形参和实参
    在一般传值调用的机制中只能把实参传送给形参,而不能把形参的值反向地传送给实参。
public static void main(String[] args){
	int a = 1;
	System.out.println(a);	//a=1

	change(a);  //a是实参
	System.out.println(a);	//a=1

	System.out.println(change(a));  //a = 10
}

//change方法
public static void change(int a){ //a是形参
	a = 10;
}
  1. 值传递和引用传递
    值传递:
public static void main(String[] args){
	int a = 1;
	System.out.println(a); //a = 1
	change(a);
	System.out.println(a);	//a = 1
}	

//change 方法
public static void change(int a){
	a = 10;
}	

引用传递:

public static void main(String[] args){
	Person person = new Person();
	System.out.println(person.name);	//null
	change(person);
	System.out.println(person.name);	//曦曦
	
}	
//定义一个方法
public static void change(Person person){
	//修改的是person这个对象的值
	person.name = "曦曦";
}

//定义一个Person类
class Person(){
	String name;
}
三、对象的创建和分析
  1. 类跟对象的关系
  • 类是一种抽象的数据类型,是对某一事物整体的描述或定义,但是并不能代表某一个具体的事物
  • 对象是抽象概念的具体实例
  1. 创建与初始化对象
  • 使用new关键字创建
//创建一个学生类; 类由属性和方法构成
public class Student{
   String name;	//属性
   int age;

   //方法
   public void study(){
   	System.out.println(this.name +"正在学习");
   }
}
  • 使用new关键词创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。构造器具有以下两个特点
    1. 必须和类的名字相同
    2. 必须没有返回类型,也不能写void
//当一个类即时什么都不写,也会存在一个方法
public class Person{
	String name;
}
//在main方法中调用
public static void main(String[] args){
	Person person = new Person(){}; 
	//== Person person = new Person();
}

Person.java文件在编译成Person.class文件的时候会自动生成一个构造器,因为创建对象的时候必须要经过一个构造方法,若类中没有构造方法,则会默认一个无参构造

public Person(){}	//构造方法
  • 构造器:

    1. 无参构造
    //作用:1.使用new关键字,本质就是在调用构造器
    	 //2.用来初始化值
    public Person(){
    	this.name = "曦曦";	//初始化值
    }
    
    1. 有参构造
    public Person(String name){
    	this.name = name;
    }
    //或
    public Person(String name,int age){
    	this.name = name;
    	this.age = age;
    }
    

注意: 如果只有有参构造,要想通过无参构造创建对象的话,需要将无参构造显性写出来,因为写了有参构造后,无参构造就没办法默认生成

//main方法中
Person person = new Person();

//一旦有了有参构造,则无参构造必须显示定义
public Person(){}

public Person(String name){
	this.name = name;
}
四、面向对象三大特性 1.封装
  • 程序设计要追求“高内聚,低耦合”
    • 高内聚:就是类的内部数据操作细节自己完成,不允许外部干涉
    • 低耦合:仅暴露少量的方法给外部使用
  • 封装(数据的隐藏)
    • 禁止直接访问一个对象中数据的实际表示,应通过操作接口来访问,这称为信息的隐藏
  • 私有属性,可以用get/set 获取、修改:
    写一个学生类的属性私有
    public class Student{
    	//属性私有
    	private String name;
    	private char sex;
    	private int age;
    
    //在main方法中如果通过 对象名.name 等方式是无法访问到name,sex等属性的
    //所以提供一些可以操作这个属性的方法,提供了一些get/set方法
    
    //get:获得这个属性值
    	public String getName(){
    		return this.name;
    	}
    //set:给这个属性设置值
    	public void setName(String name){
    		this.name = name;
    	}
    	public int getAge(){
    		return this.age;
    	}
    	//也可以用set做判断
    	public void setAge(int age){
    		if(age < 0 || age > 150){
    			this.age = 3;
    		}else{
    			this.age = age;
    		}
    	}
    
    

}
```

//通过方法设置及访问类中的私有属性
public static void main(String[] args){
	Student s1 = new Student();
	s1.setName("曦曦");
	System.out.println(s1.getName());
}

注意:可以使用 alt + Insert 自动生成get/set方法
意义:

  1. 提高程序的安全性,保护数据
  2. 隐藏代码的实现细节
  3. 统一接口
  4. 系统可维护增加了
2.继承
  • 本质是对某一批类的抽象,从而实现对显示世界更好的建模
  • extends,java中类只有单继承,没有多继承
  • 继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖,组合,聚合等
//person类
public class Person{
	public int money = 10_0000_0000;
	//如果money是private修饰的,则需要设置get/set方法来进行操作(封装)

	public void say(){
		System.out.println("说了一句话");
	}
}
//继承Person类的Student类
public class Student exdents Person{

}
public static void main(String[] args){
	Student student = new Student();
	student.say();
	System.out.println(student.money);
	//通过访问可以把父类中的数据拿到
}
  • object类是所有类的父类
  • supper&this
    父类:
public class Person{
	//属性
	protected String name = "曦曦";

	//方法
	//若改成private void print(){}的话,子类将无法继承该方法,super.print();就没办法调用
	public void print(){
		System.out.println("Person");
	}
}

子类:

public class Student exdents Person{
	private String name = "土豆";

	public void print(){
		System.out.println("Student");
	}
	//对子类和父类的方法的测试
	public void test(){
		print();	//Studnet
		this.print();	//Student
		super.print();	//Person
	}
	//对子类和父类的属性的测试
	public void test1(String name){
		System.out.println("name");		//土豆泥泥
		System.out.println("this.name");	//土豆
		System.out.println("super.name");	//曦曦
	}
}

main方法

public class Application{
	public static void main(String[] args){
		Student student = new Student();
		student.test();
		student.test1("土豆泥泥");
	}
}

构造器在子、父类直接的关系
父类:

public class Person{
	public Person(){}
}

子类

public class Student extends Person{
	public Student(){
		//默认调用了父类的无参super();
		System.out.println("调用了父类的无参构造");
	}
}

若父类的构造器是有参构造
父类:

public class Person{
	public Person(String name){
		System.out.println("调用了父类的有参构造");
	}
}

子类:

public class Student extends Person{
	public Student(){
		super(); //出错,因为无法调用父类的无参构造
		//如果要正确调用,必须要用super("name"); 才可以,或者把无参构造显示化
		System.out.println("调用了子类的无参构造");
	}
}

注意:

  1. super调用父类构造器时,super()必须在子类构造器的第一排
  2. super必须只能出现在子类的方法或构造方法中
  3. super和this不能同时调用构造方法
    一个构造函数中不能同时出现this和super两种方法,因为this函数中也有super,这会导致初始化两次,数据不安全

super&this

  1. 代表的对象不同:
    this:本身调用者的这个对象
    super:代表父类对象的应用
  2. 前提
    this:没有继承也可以用
    super:只有在继承条件下才可以使用
  3. 构造方法
    this():本类的构造
    super():父类的构造
  • 方法的重写(重写都是方法的重写,和属性无关,非静态的方法才能进行重写)
    static方法
    父类:
    public class B{
    	public static void test(){
    		System.out.println("B=>test()");
    }
    }
    

子类:

public class A extends B{
	public static void test(){
		System.out.println("A=>test()");
	}
}

application:

//静态方法的调用只和左边,定义的数据类型有关
A a = new A();
a.test();	//A=>test()

B b = new A();
b.test();	//B=>test()

非static方法:
父类:

public class B{
	public void test(){
        System.out.println("B=>test()");
	}
}

子类:

public class A extends B{
    
    //override  重写
    @Override  //注解:有功能的注释
    public void test(){
        System.out.println("A=>test()");
    }
}

application:

A a = new A();
a.test();	//A=>test()

B b = new A();
b.test();	//A=>test()

原因: b是A new出来的对象,因此调用了A的方法,由于静态方法是类的方法,而非静态是对象的方法。有static时,b调用了B类的方法,因为b是用b类定义的,没有static时,b调用的是对象的方法,而b是用A类new出来的

注意:
重写:需要有继承关系,子类重写父类的方法
1. 方法名必须相同
2. 参数列表必须相同
3. 修饰符:范围可以扩大:public>protected>default>private
4. 抛出的异常:范围可以缩小,但不能扩大:
classNotFoundException --> Exception(大)
重写:子类的方法和父类必须要一致,方法体不同

为什么需要重写:

  1. 父类的功能,子类不一定需要,或者不一定满足

重写和重载:

  1. 重载是在一个类中的
  2. 重写是有继承关系的
3.多态性
  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式
    父类:
public class Pet{
    public void run(){
        System.out.println("run");
    }
}

子类:

public Dog extends Pet{
    public void run(){
        System.out.println("跑得快");
    }
}
public cat extends Pet{
    public void run(){
        System.out.println("跑得慢");
    }
}

application:

public static void main(String[] args) {

    Pet s2 = new Cat();
    Pet s3 = new Dog();
    
    s2.run();	//跑得慢
    s3.run();	//跑得快
}

注意:
父类的引用指向子类时(用a表示),子类独有的方法a无法使用,但是父类所有的可用方法,子类都可以使用

  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
  • 多态存在的条件
    1. 有继承关系
    2. 子类重写父类方法
    3. 父类引用指向子类对象
      注意:
    4. 多态是方法的多态,属性没有多态
    5. 是子类与父类之间的
    6. 不能被重写的方法
      • static方法:属于类,它不属于实例
      • final:常量
      • private方法
4.instanceof(类型转换)

引用类型,判断一个对象是什么类型:

System.out.println(x instanceof y);//能不能编译通过
//如果有继承关系就能编译,没有就编译错误
//通过编译后,再判断True或False
//看x所指向的对象与y类是什么关系,如果x所指的对象的类比y类的高,则为False;如果x所指的对象的类别比y类的低(或等于),则为True;

例:

//object > Person > Student / Teacher
object object = new Person();
System.out.println(object instanceof object); // true
System.out.println(object instanceof Person); //true
System.out.println(object instanceof Student);//False 
System.out.println(object instanceof Teacher);//False
System.out.println(object instanceof String);//False
5.父类与子类之间的强制类型转换

父类:

public class Person{
	public void run(){
		System.out.println("run");
	}
}

子类:

public class Student{
	public void run(){
		System.out.println("跑得快");
	}

	public void go(){
		System.out.println("go");
	}
}

application1:

public static void main(String[] args){
	Person obj = new Student();
	obj.go();	//无法访问子类内部独有的方法,会报错
	((Student)obj).go(); // 通过类型转化(向下转型),可以访问子类的独有的类
}

application2:

public static void main(String[] args){
	Student student = new Student();
	student.go(); //可以访问
	
	Person person = student; //子类转换为父类
	person.go(); //无法访问
	((Student)person).go(); //强制类型转换,可以
}

总结:

  1. 父类引用指向子类的对象
  2. 把子类转换为父类,向上转型(可能会丢失自己本来的一些方法)
  3. 把父类转换为子类,向下转型,强制转换
  4. 方便方法的调用,减少重复的代码,简洁
6.static关键字详解
  1. 静态方法/属性
public class Student{
	private static int age; //静态变量 多线程!
	private double score;  //非静态的变量

	public void run(){  //非静态方法
	}

	public static void go(){  //静态方法
	}

	 public static void main(String[] args){
	 	go(); //可以直接调用
	 	run(); //报错
	 	//因为static方法属于类,非static方法是属于对象的
	 	//所以要想调用非static方法(属性)必须new一个对象
	 	Student student = new Student();
	 	student.go();
	 	student.run();
	 }
}
  1. 静态方法块
public class Student{
	//匿名方法块:可用于赋初值
	{  //第二
		System.out.println("匿名方法块");
	}

	static {//第一
		 System.out.println("静态方法块");
	}

	public Student(){	//第三
		System.out.println("构造方法");
	}


public static void main(String[] args) {
	Student student = new Student();
	//新建一个对象时,三个方法的调用顺序:1.静态 2.匿名 3.构造

	Student student1 = new Student();
	//结果:1.匿名  2.构造
	//因为静态方法与类一起加载,只加载一次
}
  1. 静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Test{
	public static void main(String[] args) {
		System.out.println(random());
		System.out.println(PI);
}

//这样导入包后就可以直接通过方法名访问方法了。
//如果导入的是import java.lang.Math;   :则需要通过Math.random(); 进行访问
  1. final
    被final修饰的类,不能被继承
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/323151.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号