学习Java之面向对象

Posted So istes immer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Java之面向对象相关的知识,希望对你有一定的参考价值。

1.对象

对象包含两个特性
状态: 指对象本身的信息(内部信息/内部变量)
行为: 实现对信息的访问/对象的操作
面向对象三大特性
封装性
继承性
多态性
①表现在继承中-----方法的重写

抽象类也体现了多态性:不同子类可以用不同的方式实现同一共同接口,其实也是方法的重写
②表现在用一个类中-----方法的重载

2.类的描述

类的定义格式
[类的修饰符] class 类名 [extends 父类名] [implements 接口名] {
… … … … … …
}
类的修饰符
public: 公共类,可以被其他类所使用,无任何限制
无修饰/默认: 仅仅能在同一个包中的其他类引用
abstract: 宣布该类不能被实例化
final:宣布该类不能有子类

3.类成员变量

①成员的访问控制修饰符

包(Package)的概念
通过包来管理类名空间可以防止同名类名的冲突
②非访问控制修符
静态变量static:属于类的变量
最终变量final:值在程序的执行过程中不会改变
易失变量volatile:可能同时被多个线程所控制和修改

4.类成员方法的访问

访问控制修饰符
公共访问控制符-public 被所有类访问
默认访问控制符 - 被同一包中其他类访问
私有访问控制符- private 被该类自身访问
保护访问控制符- protected 该类自身、同一个包中的其他类、其他包中的子类访问
私有保护访问控制符-private protected 该类自身、所有子类访问
非访问控制修符
静态方法static 属于类的方法
最终方法final 不能被子类重新定义的方法
抽象方法abstract 只有方法说明,没有具体实现
本地方法native 以其他语言实现方法功能
同步方法synchronized 用于多线程程序中的协调和同步

5.static和final

static (静态变量/静态方法)
在 Java 中并不存在全局变量的概念,但是我们可以通过 static 来实现一个“伪全局”的概念,
类的变量/方法,独立于类的对象,可以直接根据类名调用
class S {
static int A = 12, B = 34;
static void print() { … }
}
class Test {
public static void main(String args[]) {
System.out.println(“A=“ + S.A + “ B=“ + S.B);
S.print();
}
}
static方法中仅仅可以调用其他static方法
被 static 修饰的代码块,我们称之为静态代码块,静态代码块会随着类的加载一块执行
final 变量
final变量: 定义一个常数,即变量值不能改变
final类: 不能有子类
final方法: 方法不能被重写

6.传值和传引用

① 在java中所有的参数都是传值的,引用符号&的传递是C++中才有的
② 在java传参中,基本类型(byte–short–int–long–float–double–boolean–char)的变量总是按值传递
③ 对于对象来说,不是将对象本身传递给方法,而是将对象的的引用或者说对象的首地址传递给方法,引用本身是按值传递的
④ 对于String、Integer、Long,数组等,这些都相当于对象,因此传参时相当于是传引用

7.不定长参数

一个方法只能有一个不定长参数,并且这个不定长参数必须是该方法的最后一个参数
例:public void print(String… args)

8.方法的重载和方法的重写

重载
方法名相同,但方法的参数类型、参数顺序、参数个数不同
无法以返回值类型作为重载函数的区分标准
重写
子类重写父类的方法
返回值和形参都不能改变

9.单例模式

只能产生一个对象,不允许产生多个对象
例:

 public class Singleton{
 	private static Singleton  instance=null;	//2.static  private成员
	private Singleton(){					//1.private构造器
	}
	public static Singleton newInstance(){//3.public static方法
		return instance==null?instance=new Singleton():instance;
	}
public static void main(String[] args){
    	Singleton s1=Singleton.newInstance();
    	Singleton s2=Singleton.newInstance();
}

构造器使用private修饰,防止程序员在类外使用new调用,这样可以避免多个对象产生。
上述程序中s1==s2

10.抽象类

仅仅抽象类可以包含抽象方法
抽象方法: 仅仅申明了方法,但未实现
抽象类不能被实例化,例Point p = new Point()
子类继承抽象类时,必须重写抽象方法否则仍为抽象类
使用@Override伪代码好处:①当注释②为了防止覆盖方法因拼写原因,而没有覆盖,这个伪代码可以让编译器做语法检测

11. this和super

在继承中,出现重名变量、变量时,如何区分?
用this和super
this指向当前对象
super指向父类对象
具体例子看下面练习

12.类成员访问修饰符与继承的关系

私有的(private)类成员不能被子类继承
公共的(public)和保护性的(protected)类成员能被子类继承,且子类和父类可以属于不同的包
无修饰的父类成员,仅在本包中才能被子类继承
构造函数不是类成员,所以不被继承

13.instanceof 判断对象类型

前一个操作数是一个引用类型的变量
后操作数通常是一个类(或者接口),用于判断前面的对象是否是后面的类,或者其子类。
注意:前面操作数的类型要么与后面类相同,要么与后面类的父类相同,否则会引起编译错误
:ClsSuper是父类,ClsSub是ClsSuper的子类
ClsSuper o2=new ClsSub(3,2);
if(o2 instanceof ClsSub){
System.out.println(“o2 是ClsSub类型”);
}

14.接口

接口是对abstract类的进一步扩展
接口中的方法默认都是未实现的(类似于抽象方法),都是public abstract,目的是在实现接口的类之间建立一种协议
接口中的变量都是常量,默认都是public static final
在JDK1.8中,允许接口有default方法和static方法
default方法将由实现接口的类继承,该类的对象可直接调用
static方法需要通过接口名调用,不能通过对象来调用
定义
[public] interface 接口名 {
成员变量;
方法声明;
}
一个类符合某个或一组接口,利用implements
class 类名 implements 接口1, 接口2 …… {
… … …
}
例子

 interface Figure {
  double half=0.5,pi=3.14159;			//**这里的变量都是常量**
  void parameter();
  void area();
}
class Triangle implements Figure {
  double b, h;
  Triangle (double u, double v) {...}
  public void parameter() {...}
  public void area() {... }
}
class Circle implements Figure {
 double x, y, r;
 Circle(double u, double v, double m)  {... }
 public void parameter()   {... }
 public void area() {... }
}

利用接口实现多重继承

15.内部类

成员式:它们定义的位置与成员变量和成员方法类似;
局部式:定义在方法体中,属于局部范围
①静态内部类
class Outter{
int x;
static class Inner{}
}
外部类加载的时候,静态内部类也随之加载
②局部内部类
public void adc(){
class MyLocal{
}
}
③匿名内部类
addWindowListener(new WindowAdapter() {…});
作用
1.内部类可以很好的实现隐藏
做法是将内部类访问属性设置为private
2.内部类拥有外围类的所有元素的访问权限,这样对于外部的调用者而言,内部类是不可见的
一般的非内部类,是不允许有 private 与protected访问权限的,但内部类可以
3.可以实现多重继承
例子

public class Father {
    public int strong(){return 9;}
}
public class Mother {
    public int kind(){return 8;}
}
public class Son {
     class Father_1 extends Father{
         public int strong(){return super.strong() + 1;}
     }
    class Mother_1 extends  Mother{
         public int kind(){return super.kind() - 2;}
    }
    public int getStrong(){return new Father_1().strong();}
    public int getKind(){return new Mother_1().kind();}
}

4.可以避免修改接口而实现同一个类中两种同名方法的调用

16.练习

第一题
创建一个学生类,至少包含:
属性:name,sex,age
一个构造方法(带三个参数,对name,sex,age三属性初始化)
3个成员方法(方法setAge用于设置年龄,getAge用于获取年龄,outInfo()用于输出学生信息)
测试程序:
①创建2个具体学生对象
②使每个学生年龄加1(要求用成员方法实现)
③判断学生年龄是否小于20,是则打印出此相关信息
Student.java

public class Student {
	String name, sex;
	int age;
	//构造方法
	Student(String name,String sex,int age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}	
	void setAge(int age) {
		this.age = age;
	}
	int getAge() {
		return age;
	}
	void outInfo() {
		System.out.println("name = "+ name + "\\nsex = "+sex+"\\nage = "+age);
	}
	static void judge_print(Student s) {
		if(s.getAge()<20) {		
			System.out.println("输出:");
			s.outInfo();
		}
	}
	public static void main(String[] args) {
		//第一题
		Student s1=new Student("ZhangSan","男",18);	//创建两个对象
		Student s2=new Student("Lisi","女",25);
		s1.setAge(s1.age+1);						//年龄加一
		s2.setAge(s2.age+1);
		judge_print(s1);							//判断打印
		judge_print(s2);	
	}
}

输出:

输出:
name = ZhangSan
sex = 男
age = 19

第二题
创建一个研究生类GraduateStudent,该类继承于Student类,为其添加:
(1)两个私有属性:专业specially和导师teacher
1个构造方法:带有5个参数的构造方法(对所有属性初始化)
方法:specially属性和teacher属性的相关set和get方法
(2)方法的覆盖:重写Student类中的方法outInfo输出研究生相关信息
测试程序:
(1)创建1个具体学生对象,1个研究生对象
(2)打印输出两个对象的相关信息。

public class GraduateStudent extends Student{
	private String speciality,teacher;
	//构造函数
	GraduateStudent(String name, String sex, int age, String speciality, String teacher){
		super(name,sex,age);
		this.speciality=speciality;
		this.teacher=teacher;
	}
	//set和get方法
	void setSpeciality(String speciality) {
		this.speciality = speciality;
	}
	String getSpeciality() {
		return speciality;
	}
	void setTeacher(String teacher) {
		this.teacher = teacher;
	}
	String getTeacher() {
		return teacher;
	}
	//输出
	void outInfo() {
		System.out.println("\\nname = "+ name + "\\nsex = "+sex+"\\nage = "+age
				+"\\nspeciality = "+speciality+"\\nteacher = "+teacher);
	}
	public static void main(String[] args) {
		//第二题
		Student s= new Student("QianQi","女",26);
		GraduateStudent g = new GraduateStudent("WangWu","男",26,"CS","WangYiXiong");
		s.outInfo();
		g.outInfo();
	}
}

测试输出:

name = QianQi
sex = 女
age = 26

name = WangWu
sex = 男
age = 26
speciality = CS
teacher = WangYiXiong

第三题
对Student类进行修改:
新增两个成员方法setStudent,分别实现功能:第一个方法用于设置各科成绩值;第二方法用于设置年龄。
编写测试程序:
①创建一个具体学生对象,直接初始化
②利用setStudent方法修改学生的年龄,并且修改学生的成绩
③打印输出对象的相关信息
Student2.java

public class Student2 {
	String name, sex;
	int age;
	int c_score, math_score, java_score;
	//构造方法
	Student2(String name,String sex,int age,int c_score,int math_score,int java_score){
		this.name = name;
		this.sex = sex;
		this.age = age;
		this.c_score = c_score;
		this.math_score = math_score;
		this.java_score = java_score;
	}
	//设置各科成绩
	void setStudent(int c_score, int math_score, int java_score){
		this.c_score = c_score;
		this.java_score = java_score;
		this.math_score = math_score;
	}
	//设置年龄
	void setStudent(int age){
		this.age = age;
	}
	void outInfo() {
		System.out.println("name = "+ name + "\\nsex = "+sex+"\\nage = "+age
				+"\\nc_score = "+c_score+"\\nmath_score = "+math_score+"\\njava_score = "+java_score);
	}
	public static void main(String[] args) {
		//第三题(方法的重载)
		Student2 s = new Student2("ZhangSan","男",18,0,0,0);
		s.outInfo();
		s.setStudent(30);
		s.setStudent(95, 85, 79);
		System.out.println("\\n修改之后:");
		s.outInfo();
	}
}

测试输出

name = ZhangSan
sex = 男
age = 18
c_score = 0
math_score = 0
java_score = 0

修改之后:
name = ZhangSan
sex = 男
age = 30
c_score = 95
math_score = 85
java_score = 79

第四题
定义一个抽象类–形状类。其中包括求形状面积的抽象方法。继承该抽象类,定义三角形、矩形、圆形。分别创建一个三角形、矩形、圆形存入一个数组,将数组中各类图形的面积输出
Shape.java

abstract class Shape{
	double area;
	abstract public double getArea();
}

class Triangle extends Shape{
	double area;
	int a,h;
	public Triangle(int a,int h) {
		this.a=a;
		this.h=h;
	}
	public double getArea() {
		area = a*h/2;
		return area; 
	}
}

class Rectangle extends Shape{
	double area;
	int w,h;
	public Rectangle(int w,int h) {
		this.w = w;
		this.h = h;
	}
	public double getArea() {
		area = w*h;
		return area; 
	}
}

class Circle extends Shape{
	double area;
	int r;
	public Circle(int r) {
		this.r=r;
	}
	public double getArea() {
		area = Math.PI*r*r;
		return area; 
	}
}

public class Test {
	public static void main(String[] args) {
		Shape s[] = new Shape[3];
		s[0] = new Triangle(5,10);
		s[1] = new Rectangle(5,10);
		s[2] = new Circle(5);
		System.out.println("三角形面积:"+s[0].getArea());
		System.out.println("矩形面积:"+s[1].getArea());
		System.out.println("圆形面积:"+s[2].getArea());
	}
}

测试输出

三角形面积:25.0
矩形面积:50.0
圆形面积:78.53981633974483

第五题
定义一个接口,其中包含一个display()方法用于显示信息:通知类、汽车类、广告类均要实现该接口,以显示“通知内容”、“汽车油量”、“广告信息”,试编程实现并测试类的设计。创建的对象用接口引用,并通过接口引用变量执行display()方法。
TestInterface.java

interface Message{
	void display();
}

class Notices implements Message{
	public void display() {
		System.out.println("It's time to hand in the assignment!");
	}
}

class Cars implements Message{
	public void display() {
		System.out.println("The gas consumption is only 20L left!");
	}
}

class Advertisement implements Message{
	public void display() {
		System.out.println("Enjoy Coca-Cola.");
	}
}

public class TestInterface {
	public static void main(String[] args) {
		Message[] mm= { new Notices(),new Cars(),new Advertisement() };
		for(int i=0;i<mm.length;i++) {
			mm[i].display();
		}
	}
}

测试输出

It's time to hand in the assignment!
The gas consumption is only 20L left!
Enjoy Coca-Cola.

以上是关于学习Java之面向对象的主要内容,如果未能解决你的问题,请参考以下文章

Java学习笔记之十三初探Java面向对象的过程及代码实现

java学习笔记之面向对象多态

JavaSE入门学习21:Java面向对象之接口(interface)

Java学习面向对象之继承

JAVA学习面向对象之 扑克牌(初)

java学习笔记之面向对象