Java教程

期末Java面向对象程序设计稳过不挂指南(更新中)

本文主要是介绍期末Java面向对象程序设计稳过不挂指南(更新中),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

img

第三章.java类基础知识

第四节.自定义函数

·同一个类中,函数名称可以相同,即重载函数(overload),但函数参数的个数或者类型必须不同

第四章.面向对象和类

第一节.面向对象思想

·对象 = 属性 + 方法

·变量定义的变迁 :基本类型(一种变量) -> 结构体 (多种变量捆绑) -> 类(多种变量 + 方法)

·子类天然继承父类的所有东西,除了父类的private(私有)变量

·子类必须通过父类的方法才能访问父类的私有变量

public class Father {
	private int money  = 100; //私有
	long mobile = 139999L;
	
	public void hello() {
		System.out.println("Hello\n");
	}
}

public class Son extends Father{
	public void hi () {
		System.out.println("hi~~~");
	}
	
	public static void main(String[] args) {
		Son s = new Son();
//		System.out.println(s.money);  //error 父类的money是私有的,子类无法直接访问
		System.out.println(s.mobile); //Son没有定义mobile,而是通过父类继承
		s.hello(); //Son没有定义f1,而是通过父类继承的
		s.hi();	//子类可以自定义自己的成员方法
	}
}

第二节.java类和对象

A obj1 = new A();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wfmyXWmF-1622721399433)(C:\Users\DJN\AppData\Roaming\Typora\typora-user-images\image-20210603162251309.png)]

·在c/c++中, obj1 被称为指针, 在java中称为 Reference

public class Mynumber {
	int num = 5;
}

public class ArgumentPassingTest {
	public static void main(String[] a) {
		int a = 1, b = 2;
		swap(a, b);
		System.out.println("a is " + a + ", b is " + b); // a = 1 , b = 2
		
		Mynumber obj1 = new Mynumber();
		Mynumber obj2 = new Mynumber();
		
		obj2.num = 10;
		swap(obj1, obj2);
		System.out.println("obj1 is " + obj1.num + ", obj2 is " + obj2.num);
	}
	
	public static void swap(int m, int n) {
//而基本类型是直接值拷贝
		int t = m; 
		m = n;
		n = t;
	}
	
	public static void swap(Mynumber obj3, Mynumber obj4) {
//因为对象是比较庞大的,所以它的赋值是直接赋指针的,所以obj3和obj1实际上指向的是同一块内存!
//对象赋值是Reference赋值(赋值采用共享同一块内存区域)
		int t = obj3.num;
		obj3.num = obj4.num;
		obj4.num = t;
	}
}

第三节.构造函数

·变量存活周期:离它最近的大括号之中

·JVM特有GC机制,所以java不需要析构函数回收对象

·每个子类的构造函数第一行都默认调用父类的无参数构造函数super()

第四节.信息隐藏和this

·面向对象有一个法则:信息隐藏

··类的成员属性是private私有的

··类的方法是public公开的,通过方法修改成员属性的值

··通过类的方法来间接访问类的属性,而不是直接访问类的属性

class InfoHiding {
	private int id;
	
	public InfoHiding(int id2) {
		id = id2;
	}
	
	public void setId (int id2) {
		id = id2;
	}
	
	public int getId() {
		return id;
	}
}
public class InfoHidingTest {
	public static void main(String[] args) {
		InfoHiding obj = new InfoHiding(10);
		obj.setId(20);
		System.out.println(obj.getId());
	}
}

·this负责指向本类中的成员变量

·this负责指向本类中的成员方法

·this可以代替本类的构造函数

public class ThisTest {
	public static void main(String[] args) {
		MyPairNumber obj = new MyPairNumber(5);
		System.out.println(obj.sum());
	}
}

public class MyPairNumber {
	private int m, n;

	public int getM() {
		return m;
	}

	public void setM(int m) {
		this.m = m;
	}

	public int getN() {
		return n;
	}

	public void setN(int n) {
		this.n = n;
	}
	
	public MyPairNumber() {
		this(0 ,0);
	}
	
	public MyPairNumber(int m) {
		this(m, 0);
	}
	
	public MyPairNumber(int m, int n) {
		this.m = m;
		this.n = n;
	}
	
	public int sum () {
		return this.add(m, n);
	}
	
	public int add(int a, int b) {
		return a + b;
	}
}

第五章.继承,接口 和 抽象类

第一节.继承

·子类继承父类的所有属性和方法(但不能直接访问private成员)

·根据信息隐藏原则,子类继承父类的所有方法,所以可以直接使用

·子类也会继承父类的父类的属性和方法(但不能。。

·在同样方法名和参数的情况下,本类的方法比父类的方法优先级

public class Base {
	private int num = 10;
	
	public int getNum() {
		return num;
	}
}

public class Derived extends Base{
	private int num = 20;
	
	public int getNum() {
		return this.num;
	}
	
	public static void main(String[] args) {
		Derived foo = new Derived();
		System.out.println(foo.getNum()); //20
	}
}

·单根继承原则(与c++不同

·如果不写extends,java类都默认继承 java.lang.Object类

public class A {
	public A () {
		System.out.println("11111");
	}
	public A (int a) {
		System.out.println("22222");
	}
}

public class B extends A{
	public B () {
		System.out.println("33333");
	}
	public B (int a) {
		System.out.println("44444");
	}
	
	public static void main(String[] args) {
		B obj1 = new B();
		System.out.println("=====");
		B obj2 = new B(10);
	}
}

11111
33333
=====
11111
44444

但如果

public class B extends A{
	public B () {
		super();
		System.out.println("33333");
	}
	public B (int a) {
		super(a);
		System.out.println("44444");
	}
	
	public static void main(String[] args) {
		B obj1 = new B();
		System.out.println("=====");
		B obj2 = new B(10);
	}
}

11111
33333
=====
22222
44444

第二节.抽象类和接口

抽象类

·一个完整的类(所有方法都有实现)才可以被实体化,才可以被new出来

public abstract class Shape {
	int area;
	public abstract void calArea();
}
public class Rectangle extends Shape{
	
	int width;
	int length;
	
	public Rectangle (int length, int width) {
		this.length = length;
		this.width = width;
	}
	
	public void calArea () {
		System.out.println(this.length * this.width);
	}
	
	public static void main(String[] args) {
		Rectangle rect = new Rectangle (5, 10);
		rect.calArea();
	}
}

接口

·如果类的所有方法都没有实现,那么这个类就算是接口interface

public interface Animal {
	public void eat();
	public void move();
}

·类只可以继承extends一个类,但是可以实现implements多个接口,继承和实现可以同时

·继承抽象类,必须实现所有abstract的方法;实现多个接口,必须实现接口中所定义的所有方法

·接口不算类,或者说是特殊的类

·接口可以继承(多个)接口,没有实现的方法将会叠加

·接口里可以定义变量,但一般是常量

public interface ClimbTree {
	public void climb();
}

public abstract class LandAnimal implements Animal {
	public abstract void eat();
    
	public void move() {
		System.out.println("I can move by feet");
	}
}

·extends 必须写在 inplements 的前面

public class Rabbit extends LandAnimal implements ClimbTree {
	//继承一个抽象类,实现一个接口,都要实现abstract方法
	public void eat() {
		System.out.println("Rabbit : I can eat");
	}
	
	public void climb() {
		System.out.println("Rabbit : I can climb");
	}
}

public interface CatFamily extends Animal, ClimbTree{
	//CatFamily接口继承于两个接口,相当于将多个接口中未实现的方法都“承载”过来
	
	//eat()
	//move()
	//climb()
}

public class Tiger implements CatFamily{
	
	public void eat() {
		System.out.println("eat");
	}
	
	public void move() {
		System.out.println("move");
	}
	
	public void climb() {
		System.out.println("climb");
	}
}

·抽象类和接口共同点: 两者都不能被实例化,不能new操作

·抽象类和接口不同点

··抽象类abstract, 接口interface

··抽象类可以有部分方法实现,接口所有方法都不能有实现

··一个类只能继承一个(抽象)类,但可以实现多个接口

··接口可以继承extends多个接口

··抽象类可以有构造函数,接口没有构造函数

··抽象类可以有main,也能运行,接口没有main函数

··抽象类方法可以有private/protected,接口方法都是public

第三节.转型,多态和契约设计

类转型

·变量(基本类型变量)支持互相转化,比如 int a = (int)3.5; // a = 3(把小数部分截断)

·类型可以相互转型,但是只限制于有继承关系的类

··子类可以转换成父类(接口也算父类)(从大变小,即向上转型),但父类不能转换成子类

	Human obj1 = new Man(); //OK, Man extends Human
	Man obj2 = new Human(); //illegal

·父类转为子类有一种情况例外

··就是这个父类本身就是从子类转化过来的

	Human obj1 = new Man();
	Man obj2 = (Man) obj1; //OK,obj1 is born from Man class

多态

·类型转换,带来的作用就是多态

·子类继承父类的所有方法,但子类可以重新定义一个名字,参数和父类一样的方法,这种行为就是重写(覆写,覆盖,overwrite/override, not overload(重载))。重写是指子类的方法替换掉父类的方法

·而重载overload是值函数名一样,形参不一样,是指两个不同的方法

·子类的方法的优先级是高于父类的

public class Man extends Human{
	
	public void eat() {
		System.out.println("I can eat more!!!");
	}
	
	public void plough() { }
	
	public static void main(String[] args) {
		Man obj1 = new Man();
		obj1.eat(); //call Man.eat()
		Human obj2 = (Human) obj1;
		//obj2转型前是obj1,而obj1是Man类型,所以obj2本质上是Man类型
		obj2.eat(); // call Man.eat()
		Man obj3 = (Man) obj2;
		//obj2本身也是脱胎于obj1,由于obj3是一个Man对象
		obj3.eat(); // call Man.eat()
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ktCGZSSx-1622810760754)(C:\Users\DJN\AppData\Roaming\Typora\typora-user-images\image-20210604110037890.png)]

·obj2相当于是拿了块布把obj1多余的部分盖起来了,obj3把这块布又掀开了,然后再指向obj3

	obj1 == obj2; //true
	obj2 == obj3; //true
	//意味着这三个东西都指向同一块内存(不要忘了它们是reference,值代表指向的内存)

·多态的两个作用

··多态:可以以统一的接口来操纵某一类中不同的对象的动态行为

··多态:对象之间的解耦(只要送进去一个实现了Animal接口的对象(Cat,Dog,new,匿名类

public interface Animal {
	public void eat();
	public void move();
}

public class Cat implements Animal{
	
	public void eat() {
		System.out.println("Cat : eat");
	}
	
	public void move() {
		System.out.println("Cat : move");
	}
}

public class Dog implements Animal{
	
	public void eat() {
		System.out.println("Dog : eat");
	}
	
	public void move() {
		System.out.println("Dog : move");
	}
}

public class AnimalTest {

	public static void main(String[] args) {
		Animal[] as = new Animal[4];
		as[0] = new Cat(); //隐性地做了转型操作,因为Cat继承于Animal,实现了它这个接口,子类可以转型成父类
		as[1] = new Dog();
		as[2] = new Cat();
		as[3] = new Dog();
		
		for (int i = 0; i < as.length; i ++ ) {
			as[i].move(); //调用每个元素自身的move方法
		}
		
		for (int i = 0; i < as.length; i ++ ) {
			//这个方法前不需要写类名 
			haveLunch(as[i]);
			//haveLunch的形参是Animal对象,而as这个数组也是Animal对象
			//而eat调的肯定不是Animal的方法,而是每个元素自身的eat
		}
		
		haveLunch(new Cat()); //隐性转型 Animal a = new Cat(); haveLunch(a);
		haveLunch(new Dog());
		//Animal是个接口,不可以new的,但在这里可以new出来,条件是
		//把它eat方法和move方法给补全,就可以产生一个匿名的类
		//这个类,没有名字但是可以产生出这样一个对象,反正这个类只要用一次
		//28到38行算一句话,隐藏地new了一个Animal的子类
        
        //只需要传进去一个实现Animal接口的对象,就可以运行haveLunch方法
		haveLunch(
						new Animal()
						{
							public void eat() {
								System.out.println("Anonymous : eat");
							}
							
							public void move() {
								System.out.println("Anonymous : move");
							}
						});
	}
	
	public static void haveLunch(Animal a) {
		a.eat();
	}
}

契约设计

总结

类转型

子类可以转父类,父类不可以转子类(除非父类对象本身就是子类)

多态

子类转型成父类后,调用普通方法,依旧是子类的方法

契约设计

类不会直接使用另外一个类,而是采用接口的形式,外部可以“空投“这个接口下的任意子类对象

第六章.static, final 和 常量设计

第一节.static

java中的static关键字(可作用在)

·变量

·方法

·类

·匿名方法块

静态变量, 类共有成员

public class Potato {
	static int price = 5;
	String content = "";
	public Potato (int price, String content) {
		this.price = price;
		this.content = content;
	}
	public static void main(String[] a) {
		System.out.println(Potato.price); //5			//Potato.contend -> wrong
		System.out.println("===========");
		Potato obj1 = new Potato(10, "青椒土豆丝");
		System.out.println(Potato.price); //10
		System.out.println(obj1.price); //10
		//Potato.price和obj1.price在内存中是同一个东西
		//也就是说,在内存中只有一个price,这个price既可以通过Potato.price,也可以通过obj1.price
		
		System.out.println("============");
		Potato obj2 = new Potato(20, "酸辣土豆丝");
		System.out.println(Potato.price); //20
		System.out.println(obj2.price); //20
	}
}

·static变量只依赖于类存在(通过类即可访问),不依赖于对象实例存在。即可以通过Potato.price即可访问

·所有的对象实例,如obj1和obj2关于price变量的值都共享存储在一个共同的空间(栈)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BFXe519f-1622810760759)(C:\Users\DJN\AppData\Roaming\Typora\typora-user-images\image-20210604204412536.png)]

static方法

这篇关于期末Java面向对象程序设计稳过不挂指南(更新中)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!