Java:从类到泛型

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_41374099/article/details/100765046

前言

这个东西终于有老师教了,我对一期后达到的水平没什么要求,这门课随便过了就行。那么,开始随便瞎JB写吧。


public class Test{
	public static void main(String[] args){
		System.out.println("hello");
	}
}

Java中的函数不能单独存在,全部都要放在类中。一个 public class A{} 形式的类一个 .java文件最多有一个,而且这个一级的公共类(不是嵌套的)的名字和包含它的文件名应该相同。如果没有公共类,那么文件名字也应该与包含

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

这个入口函数的类名相同。每个类中同样可以存着入口函数,也可以没有入口函数。
   \;
   \;

属性与方法

比起C++中的类,Java中的类没有析构函数,可以不写public、private、protected限定符。麻烦的是如果要写限定符,每个函数或者变量需要单独考虑,有些加有些不加。

a 访 A 对象a访问类A成员

修饰符 同类 子类(同包) 非子类(同包) 子类(不同包) 非子类(不同包)
public
protected 不可以
不可以 不可以
private 不可以 不可以 不可以 不可以

(包和子类的概念下面再介绍)

class _A{
	private int m_a;//私有的变量
	public void func(){}    //公共权限的函数
	protected int f1(){}   //被保护的函数

	void move(){}  //不写限定符的是友好的,这个方法就是友好方法
}

   \;
   \;

static

class A{
	int a;  //实例变量
	static b; //类变量
	void fun(){}   //实例方法
	static void func(){}   //类方法
}

没有static 修饰的类属性称为实例变量,反之叫类变量。放到函数上就是实例方法与类方法,类方法(用static 修饰的)只能调用该类的类方法,不能调用实例方法。而实例方法就随意了。

static修饰的变量或方法自然就和实例化无关了,可以直接通过类名来调用。
   \;
   \;

重载与this

class B{
	double getArea(double x,int y){ return x*y; } 
	int getArea(int x,double y){return (int)(x*y);}
	double getArea(float x,float y,float z){   return  (x*x + y*y + z*z)*2.0; }

	void func(){
		System.out.println(	this.getArea(1,2) );  //this的使用
	}
}

重载也是C++中有过的知识,意思是允许写几个相同命名的函数,只是保证返回类型、传入参数的类型和个数不一样就行了。这么写下的几个函数自己使用就使用了,实际推导到底是哪个函数这个靠编译机自己做。

this关键字在类中函数里使用,可以通过点操作调用类中元素。

   \;
   \;

package

package module1;
package module2.module3; 
//...

所有的 .java 文件都可以放在包里面,引用包时语法是 package 包名;
如果没有写这个package语句,那么 .java文件默认是一个无名包的一部分。

如果package语句引用的包有用点操作(如下面第二句),那么写了这句话的 .java 文件应该放在 module2\module3这样的目录之下。
   \;
   \;

import

//引用类库中的类
import java.applet;     //包含所有的Java Applet实现的类
import java.awt;        //包含抽象窗口工具集中的图形、文本、窗口GUI类
import java.awt.image;     //包含抽象窗口工具集中的图像处理类
import java.lang;      //包含所有的基本语言类
import java.io;        //包含所有的输入输出类
import java.net;        //包含所有网络功能实现的类
import java.uti;;       //包含有用的数据类型类

通过import导入包中的类,一个Java文件中的import语句必须写在package语句和其他内容之间,如果没有package的话import语句当然写最开头啦。

如果要导入一个包中的所有类,可以用通配符 * 代替 import java.awt.*;
而写的具体的话就只是引用该文件的类而已(文件名毕竟和类名一样嘛)

   \;

继承

class A{}   //默认继承与Object,和下面这句一样
class A extends Object{}

class Parent{  //父类
	private int a;
	int b;
	protected int c;
	public int d;
}
class Children extends Parent{  //子类继承于父类

	void func(){
		//a=0; error
		b=1;
		c=2;
		d=3;
		System.out.println(b+c+d);
	}
}

类的三大概念,封装、多态、继承。类能封装这个就不用说了,多态由函数的重载实现函数的多态,抽象类或者接口来实现类的多态——多态就是多个不同的东西可以对应这同一个入口或者解决方案……继承就是保留其他类(被继承的类)部分的功能,又由新需求在子类上拓展出新的功能。

  • Java不允许多继承,只有单继承

   \;

上转型对象

Parent p=new Child();
p.print();//Child类中重写的print
Parent p1=new Parent();
p1.print();

用一个父类对象来创建其子类,将会得到一个上转型对象p。上转型对象p与普通用父类定义的对象p1的区别是p调用重名方法时调的是子类的,其他都和p1相同。p和p1一样能调用父类的属性,父类的方法(没被重写的)

   \;

隐藏父类变量

如果有东西我又不想继承过来,那么隐藏起来就是一种解决方法。说是隐藏,其实也就是对变量的重写而已,重写的变量和父类的变量区别是类型不同。
   \;

重写方法

在子类里写一个和父类中的一模一样的方法,这就是重写该方法。
   \;

super

class Parent{
	int x,y;
	A(){  //默认构造函数
		x=1,y=2;
	}
	A(int x,int y){
		this.x = x,	thi.y = y;
	}
}
class Children extends Parent{
	int z;
	B(){  //默认构造函数
		//super();
		z=3;
	}
	B(int x,int y){  
		super(x,y);//调用父类构造函数完成对x,y的初始化
		z=3;
	}
}

super函数可以调用父类的构造函数,也可以操作被隐藏(重写)的类元素 :
super.x ; super.func();

   \;

final类&final方法

final class A{
	final int fun(){}
}

final类不能被继承,final方法不能被重写(如果这个方法的类可以不是final的话,如果是那么这个方法的final关键字就没有意义)
   \;

抽象类

abstract class A{ //抽象类
	public boolean move(){} //实例方法
	public abstract int run();//抽象方法
}

abstract类是用于将类的特性合在一起。在C++中做设计模式时常常用没有实现的抽象类来作为几个相似类的接口。
抽象方法不能实现,需要留给子类来实现。抽象类或者是父类的对象可以定义子类的实例,所以这样的对象也叫上转型对象。

  • 不允许final和abstract同时修饰。
  • 抽象类不能new

   \;

接口

接口只提供方法声明,不提供方法实现

//接口的声明
interface Printable{
	final int MAX=100;
	void add();
	float sum(float x,float y);
}
//接口的使用
class A implements Printable,Addable{}  //类A使用接口Printable,Addable
class Dog extends Species implements Eatable,Sleepable   //类Dog既在继承,又在使用接口
class Some implements Printable{
	//接口的实现方法必须加public关键字
	public float sum(float x,float y){System.out.println("sum");}
}

接口和类很像,就像类和结构体很像一样,都是在后者基础上增加衍生的。接口同样可以被继承,继承的仍然是一个接口(子接口)。

接口中的方法默认是publicabstact的,所以接口声明时可以省略这两个,但是类在实现的时候一定要加public

  • 接口中不能定义成员变量,只能定义成员常量
  • 抽象类只能被单继承(实现),但是接口可以被多实现
  • 抽象类是封装共有的属性和行为,而接口只封装共有的的行为
  • 抽象类中的抽象方法(没有实现的)都需要abstract关键字,接口类中都是抽象方法(都不能实现),可以忽略abstract关键字

   \;

内嵌类

在一个类里定义另一个类,前者把后者看做自己的成员。内嵌类不能声明static成员,也就是不能声明类变量、类方法。

   \;

匿名类


interface faceID{
	
	void look();
	void sayHello();
}
class Vivo implements faceID{
	
	public void look(){
		System.out.println("Vivo::look");
	}
	public void sayHello(){
		System.out.println("Vivo::hello,hello");
	}
}

class Apple{
	public void faceID(faceID a){
		System.out.println("Apple::faceID");
		a.look();
		a.sayHello();
	}
}

public class Test{
	public static void main(String[] args){
			Apple apple=new Apple();
			apple.faceID(new Vivo());
			apple.faceID(new faceID(){//用接口或抽象类来定义一个匿名类,并实现其所有接口
				public void look(){
					System.out.println("Apple::look");
				}
				public void sayHello(){
					System.out.println("Apple::hello");
				}
		});
		
	}
}
//result
Apple::faceID
Vivo::look
Vivo::hello,hello
Apple::faceID
Apple::look
Apple::hello

匿名就是无名,没有给定义的类分配一个名字,所以不可能用匿名类来声明对象,只能在定义的时候创建。
匿名类不可以声明static成员。

   \;

异常类

public class Test{
	public static void main(String[] args){
		int n=0,m=0,t=0;
		try{
			t=9999;
			m = Integer.parseInt("8888");
			n= Integer.parseInt("12s3a");
			System.out.println("我没有异常抛出")
		}
		catch(Exception e){
			System.out.println("异常");
			n=123;
		}
		System.out.println("n="+n+"m="+m+"t="+t);
	}
	
}

当程序出错时,编译器用异常类Exception的相应子类创建一个异常对象,并等待处理。

有时需要抛出的异常消息比较有个性,需要自定义异常类。

//自定义异常类

class GG_Exception extends Exception{
	String message;//异常的消息显示
	GG_Exception(int n) {
		message=n+"不是正数";
	}
	public String getMessage(){
		return message;
	}
	
}
class GG{
	public void f(int n) throws GG_Exception{
		if(n<0){
			GG_Exception e=new GG_Exception(n);
			throw(e);
		}		
		double num=Math.sqrt(n);
		System.out.println(n+"的平方根是"+num);
		
	}	
}

public void test(){
	public static void main(String[] args){
		GG gg=new GG();		
		try{//等着抛异常
			gg.f(-12);
		}
		catch(GG_Exception e){
			System.out.println(e.getMessage());
		}
}
//result
-12不是正数

   \;

泛型(Generics)类

class Chorus<E,F>{
	void makeChorus(E person,F instructor){
		instructor.toString();
		person.toString();
	}
}

泛型和模板有点相似。语法class A<E> 声明一个泛型类,A是泛型类的名称,E是其中的泛型列表。E可以是任何对象或接口,但不能是基本数据。

通过泛型可以建立类型安全的数据结构,在使用泛型建立数据结构时,不用进行强制类型转换(不要求进行运行时类型检查)

猜你喜欢

转载自blog.csdn.net/weixin_41374099/article/details/100765046