return
方法定义中有返回值类型的设置,使用return返回一个相同类型的数据
在方法中,可以使用return关键字,结束方法的运行
static
static 修饰的成员变量,不属于对象的数据结构,属于类的变量
static 修饰的成员变量和类的信息,存储在方法区
创建一个类的对象[即实例化],在堆内存 开辟一块空间,存储该类对象所拥有的成员变量
堆内存 存储类的非静态成员变量
方法区类 存储类的静态成员变量以及静态成员方法与代码片段
一个类的静态成员变量只有一份,非静态成员变量的对象有多份
static静态成员变量 属于类
每个对象共享数据[都能修改与使用]
public class Demo1Cat {
String name;
String sex;
int age;
//统计出现(对象)次数
static int count; //静态变量
public Demo1Cat(String name,String sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
count++; //每次创建一次对象,数量加一 计算
}
}
class TestCat{
public static void main(String[] args) {
//static 静态变量 可通过类名 或引用对象的变量 直接访问修改静态变量
System.out.println(Demo1Cat.count);// 0
Demo1Cat cat=new Demo1Cat("LL","公猫",3); //构造+1 1
Demo1Cat.count++;//cat1.count++; 2
System.out.println(Demo1Cat.count);
Demo1Cat cat1=new Demo1Cat("HH","母猫",1); //3
Demo1Cat.count++; //cat2.count++; 3
System.out.println(Demo1Cat.count);
}
}
非静态成员变量与非静态成员方法,属于对象,只能通过对象调用
静态成员变量与静态成员方法,属于类,通过类名或对象的引用变量进行调用
类名.静态成员变量
类名.静态方法()
static修饰的方法,不需要针对对象进行操作,其运行结构仅仅与输入的参数有关;
static修饰的方法 ,调用时无具体对象,不能调用非静态成员变量与成员方法
非静态成员变量与非静态成员方法,在static修饰的方法中,
先创建相应对象
再通过引用变量对/非静态成员变量与非静态成员方法进行调用
静态成员方法,在具体对象的情况下,无法调用非静态成员变量及非静态成员方法
非静态成员方法 可调用静态成员变量及成员方法
public class Demo3Dog {
String name;
String sex;
static int count;
//输出狗的数量
public void print(){
System.out.println(name+"---"+sex);
System.out.println(count);
}
public static void add(){
count++;
//System.out.println(name+"---"+sex);
//this.print();
//静态成员变量与静态成员方法,属于类;非静态成员变量与非静态成员方法,属于对象
//非静态成员变量与非静态成员方法,在static修饰的方法中,先创建相应对象,再通过引用变量对/非静态成员变量与非静态成员方法进行调用
Demo3Dog d1=new Demo3Dog();
d1.name="哈哈";
d1.sex="ll";
d1.print();
}
}
class TestDog{
public static void main(String[] args) {
Demo3Dog.add();
}
}
静态无法调用非静态[除非提供对象]、非静态可调用静态
final
final 修饰的类,不能被继承,避免滥用继承造成的危害
final 修饰的方法 不能被重写[子类不能重写父类] ,防止子类在定义自己的方法时,不经意被重写 [可在自身类中重载]
final 修饰的成员变量 不能被修改数据值[常量] 且必须有初始值;若无初始值,则编译错误
jdk中许多类都是被final修饰[String.java]
常量
static + final 修饰成员变量
本质是常量 名字全部大写 多个单词_(下划线)分割
功能:直接类调用+值固定不可修改
class FianlTest{
//final int b; 无初始值编译错误
final int b=10; //final修饰的成员变量 值不能再被修改 且必须有初始值 放置方法区的常量池中
static int c;//静态成员变量 未被赋值的静态变量有默认值0
static int d=11;//静态成员变量
//static final int E; 无初始值,编译错误
static final int E=12;//常量[静态不能被修改的成员变量]
}
class Test2{
public static void main(String[] args) {
//System.out.println("常量:"+FianlTest.b);
// 编译错误 b为非静态成员变量 需要先创建对象,才能调用
FianlTest t=new FianlTest();
System.out.println("成员变量b:"+t.b);//成员变量b:10
//t.b=12; 修改final修饰的常量b的值 编译错误 final修饰的变量不能再被修改值
//调用静态变量 类名.静态成员变量
System.out.println("静态成员变量c:"+FianlTest.c); //静态成员变量c:0
//未被赋值的静态变量有默认值
System.out.println("静态成员变量d:"+FianlTest.d);//静态成员变量d:11
FianlTest.c=15; //修改静态成员变量c的值
System.out.println("静态成员变量c:"+FianlTest.c); //静态成员变量c:15
//静态变量的值可被修改
System.out.println("常量D:"+FianlTest.E);//常量D:12
//FianlTest.E=20; 修改常量值 编译错误 final修饰的变量不能再被修改值
}
}
Math.PI
Math类中,public static final double PI
Integer.MAX_VALUE
Integer类中,public final class Integer
对象数组
对象数组的元素不是基本类型,是引用类型
对象数组的初始化和基本类型数组的初始化方式一样,但元素是对象引用
对象数组创建之后,元素的默认值是null
public class Demo5Array {
public static void main(String[] args) {
Point[] ps; //数组(对象数组)
ps=new Point[4];//表示数组的长度 数组元素默认值是null
ps[0]=new Point(2,2);
ps[1]=new Point(3,3);
ps[2]=new Point();
//类在创建对象后,默认成员变量值int 0;
for(int i=0;i<ps.length;i++){
ps[i].print();
//(2,2),(3,3),(0,0),异常
}
//ps[3]未创建对象 指向为null
//空指针异常java.lang.NullPointerException
ps[3]=new Point(5,5);
for(int i=0;i<ps.length;i++){
ps[i].print();
//(2,2),(3,3),(0,0),(5,5)
}
}
}
class Point{
int x;
int y;
public Point(){
}
public Point(int x,int y){
this.x=x;
this.y=y;
}
public void print(){
System.out.println("("+x+","+y+")");
}
}
赋值
引用变量指向同一个引用对象地址 即一个引用变量修改对象成员变量,均改变
//main函数中加入
//赋值
ps[0]=ps[1]=ps[2]=ps[3];
//将ps[3]的引用对象地址赋值给ps[2],ps[1],ps[0]
//四个引用变量指向同一个引用对象地址 即一个引用变量修改对象成员变量,均改变
for(int i=0;i<ps.length;i++){
ps[i].print(); //四个(5,5)
}
ps[2].x=7;
ps[3].y=8;
for(int i=0;i<ps.length;i++){
ps[i].print(); //四个(7,8)
}
二维数组
二维数组[一维度][二维度]
一维度必须定长,二维度每个数组的长度可以不定长
二维数组共有的元素为 一维长度*二维长度
计算两个点直接的距离
//创建一个Point类型维数组,存放Point对象,计算两个点直接的距离
public class Demo7PointLine {
public static void main(String[] args) {
Random random=new Random();
Point[][] points=new Point[5][2];
//初始化 Point对象与点的值
for(int i=0;i<points.length;i++){
for(int j=0;j<points[i].length;j++){
points[i][j]=new Point(random.nextInt(10), random.nextInt(10));
//new 创建十次Point对象
}
}
double[] line=new double[5];
for(int i=0;i<points.length;i++){
// line[i]=Point.lineCount(points[i][0],points[i][1]);
//调用Point中的静态方法,计算两个对象点之间的距离
//计算一个点到另一个点距离的方法
line[i]=points[i][0].distance(points[i][1]);
}
for (int i=0;i<points.length;i++){
System.out.println("两个点为: ");
points[i][0].print();
points[i][1].print();
System.out.println("两点之间的长度为: "+ line[i]);
}
}
}
class Point{
int x;
int y;
public Point(){
}
public Point(int x,int y){
this.x=x;
this.y=y;
}
public void print(){
System.out.println("("+x+","+y+")");
}
public double distance(Point b){ //this作为一个点
return Math.sqrt(Math.pow((this.x-b.x),2)+Math.pow((this.y-b.y),2));
}
public static double lineCount(Point a,Point b){
return Math.sqrt(Math.pow((a.x-b.x),2)+Math.pow((a.y-b.y),2));
}
}
abstract
用abstract关键字修饰的类称之为抽象类
抽象类不能实例化,抽象类的意义在于“被继承”
抽象类为子类“抽象”出公共部分,通常也定义了子类所必须实现的抽象方法
普通类不能有抽象方法 ,否则编译错误
抽象方法[存在与抽象类 与接口中]
class A{
public abstract void b(); //编译错误
// 普通类中 不能有abstarct关键字
}
抽象类:
有成员变量、成员方法(实现了的方法和没有实现的抽象方法[抽象方法])
无抽象成员变量
抽象类有构造方法
抽象类不能被实例化 也无法放在一个普通类中
子类继承抽象父类
需实现父类的抽象方法,否则子类也需要设为抽象类
作为抽象类的子类,若子类不做抽象类,则继承父类所有抽象方法 并全部重写; 若没有具体函数体,可空实现[解决编译错误]
作为抽象类的子类 可依旧为抽象类,则这个子类可不实现父类中的抽象方法,也可以选择实现
抽象父类
abstract class Animal{
int age;//年龄
double hp;//生命值
//构造函数
public Animal(){
System.out.println("Animal....调用父类构造体");
}
public void eat(String food){
System.out.println("吃:"+food);
}
//抽象方法 abstract修饰 没有方法体
//休息方式不同,不实现此方法,让子类来实现 规范了所有子类 必须重写此抽象方法
public abstract void sleep();
public abstract void sing();
}
普通继承类[子类]
//子类继承抽象父类 需实现父类的抽象方法 否则子类也需要设为抽象类
//作为子类,继承父类所有抽象方法 并全部重写; 若没有具体函数体,可空实现[解决编译错误]
class Bird extends Animal{
@Override
public void sleep() {
System.out.println("鸟在鸟窝里休息");
}
@Override
public void sing() {
//空实现 方法体中无任何代码,只为解决编译错误
}
public void egg(){
System.out.println("鸟下蛋了!!!");
}
}
抽象继承类[子类]
//蜗牛类 抽象类的子类 依旧为抽象类 则这个子类可不实现父类中的抽象方法,也可以选择实现
abstract class WoNiu extends Animal{
public WoNiu(){
System.out.println("WoNiu构造器.....");
}
@Override
public void sleep() { //可重写或不重写
System.out.println("蜗牛在蜗牛窝里休息");
}
}
抽象继承类的普通子类
//定义一个蜗牛的子类,提供一个爬行的方法
class GoldWoNiu extends WoNiu{ //蜗牛的子类
@Override
public void sing() {//空实现
}
public void run(){ //爬行方法
System.out.println("金蜗牛在爬行.....");
}
}
主函数
每次只要创建向上造型的对象,就会先调用抽象父类的构造器
先构造父类,再构造子类
public class Demo8Abstarct {
public static void main(String[] args) {
//抽象类不能被实例化 也无法放在一个普通类中
//Animal a=new Animal(); //抽象父类
//WoNiu w=new WoNiu();//抽象子类
Animal a1=new Bird();//向上造型
//输出: Animal....调用父类构造体
//抽象类有构造方法 通过向上造型自动构造
a1.sleep();
//输出: 鸟在鸟窝里休息
// a1.egg(); 编译错误 编译时 a1是Animal类型 没有egg方法 编译错误
//强转
//方法一
if(a1 instanceof Bird){
Bird b1=(Bird) a1;
b1.egg(); //强转为Bird类后,调用Bird中的方法
//输出: 鸟下蛋了!!!
}
//方法二
// if(a1.getClass()== Bird.class){
// Bird b1=(Bird) a1;
// }
//父类与子类的子类
Animal w1=new GoldWoNiu();
//输出: Animal....调用父类构造体
//输出: WoNiu构造器.....
//GoldWoNiu的父类是WoNiu WoNiu的父类是Animal
//均会被构造
//父类与子类
WoNiu w2=new GoldWoNiu();
//输出: Animal....调用父类构造体
//输出: WoNiu构造器.....
w1.sleep();
//输出: 蜗牛在蜗牛窝里休息
if(w1.getClass()==GoldWoNiu.class){
GoldWoNiu g1=(GoldWoNiu) w1;
g1.run();
//输出: 金蜗牛在爬行.....
}
}
}