# 기타제어자 - static final abstract (접근제어자 public protected default private)
# static static붙힌것과 주소만들어주는것( A o=new A() )은 메모리에 올라감
static이 붙으면 오버라이딩 안됨( static은 고정된, 정적인 이라는 뜻 )
의미 : 클래스에 속한것이라는 의미를 가진다.
위치 : 멤버변수앞, 메서드앞
# 멤버변수앞에 선언되는 static : 객체간에 어떤 변수를 공유하고자할때
(static이 메서드앞에 선언될 때 : 편하게 사용하자..)
[ex]
class A{
int a=100;
public static void main(String args[]){
System.out.println(a);
}
}
//오류나는이유는..순서상
// 1. java A 실행시 A.class를 현재폴더에서 찾는다.
// 2. 클래스A를 메모리에 로딩시킨다.(클래스A에 static이 선언된 모든것을 메모리에 올린다.)
// 3. 클래스A에 있는 main메서드를 호출한다.
// 즉, 위예제는 메인메서드가 먼저 메모리에 올라가있어서 a를 찾을수 없다.
(주소를만들어주거나 변수a앞에 static을 붙히면 해결가능)
[ex]
class A{
static int a=100; // 클래스변수(모든객체가 공유하는 변수)
int b=200; // 객체변수
A(){
a++;
b++;
}
}
class B{
public static void main(String args[]){
A o1=new A(); // => 생성자 부름 => a=101
A o2=new A(); // => 생성자 부름 => a=102
A o3=new A(); // => 생성자 부름 => a=103
System.out.println(A.a+","+o1.b); // static이 붙은것은 클래스명.클래스변수 로 부른다.
// (static이붙어있어서 o1.a 나 A.a나 똑같음)
System.out.println(A.a+","+o2.b); // o1.a o2.a o3.a 로 불러도 a는 클래스변수이므로
// 객체변수와 달리 101이 아닌 103이 출력됨
System.out.println(A.a+","+o3.b); // 즉, 클래스변수는 모든객체가 공유하기때문에 객체가
// 생성될때마다 그 값은 변함
}
}
//103 201
//103 201
//103 201
[ex] 아래는 알맞게 수정하시오
class Child{
int candyNum=10;
String name;
Child(String n){
name=n;
}
void eatCandy(){
candyNum--;
System.out.println("남은사탕수:"+candyNum);
}
}
class A{
public static void main(String args[]){
Child child1=new Child("철수");
Child child2=new Child("순이");
child1.eatCandy();
child2.eatCandy();
}
}
[an]
class Child{
static int candyNum=10; //static이라서 클래스에속함을 의미 => 각 개체에서 공통으로 사용(공유)
String name;
Child(String n){
name=n;
}
void eatCandy(){
candyNum--;
System.out.println("남은사탕수:"+candyNum);
}
}
class A{
public static void main(String args[]){
public static void main(String args[]){
Child child1=new Child("철수");
Child child2=new Child("순이");
child1.eatCandy();
child2.eatCandy();
}
}
}
# static이 메서드앞에 선언될 때 : 편하게 사용하자..
(멤버변수앞에 선언되는 static : 객체간에 어떤 변수를 공유하고자할때)
[ex]
class A{
static void m1(){ //static이 붙는것은 주소를 만들필요없이 클래스명으로 바로 부를수있다.
System.out.println(1);
}
void m2(){
System.out.println(2);
}
}
class B{
public static void main(String args[]){
A.m1(); // static이 붙은 메서드이기때문에 다른클래스에서 주소만들어줄필요없이
// 클래스명.메서드명 으로 바로 부를수 있다.
A o=new A(); // 만약같은클래스에서 static이 붙은 매서드를 부를때에는 클래스명 생략가능
// ==> A.m1() --> m1()
o.m2(); // 물론 static이붙은 클래스변수도 같은클래스안이면 생략가능 A.a --> a
}
}
[ex]
class A{
int a=100;
public static void main(String args[]){ // 에러이유는... 실행순서상 static과
// 주소를만들어주는것이 메모리에 먼저 올라가고
System.out.println(a); //컴파일에러 // 메인메서드를 실행하기 때문에
// int a=100;이라는걸 인식할수 없음 ??
}
}
// 해결책은 변수a를 클래스변수로 만들어주거나 아니면 아래 예제와 같이
// 클래스A의주소를 만들어주어 메모리에 올리면됨
[ex]
class A{
static int a=100;
int b=200;
static void m1(){
System.out.println(a);
A o=new A();
System.out.println(o.b);
}
void m2(){
System.out.println(a);
System.out.println(b);
}
public static void main(String args[]){
m1();
A o=new A();
o.m2();
}
}
//간단히
class A{
static B o=new B();
}
class B{
void m(int n){
System.out.println(n);
}
}
class C{
public static void main(String args[]){
// B a=A.o;
// a.m(100);
A.o.m(100); //위 두줄을 간단히 한줄로 나타낼수있음
} //즉 static이라서 클래스이름으로 바로땡겨올수있음
}
#static블럭
클래스가 메모리에 로딩될때 자동으로 호출됨!
생성자보다 먼저 실행됨!!! 우선순위가 더 높음!! 즉, 객체 생성보다 먼저 실행됨!!
[ex]
class A{
static{
System.out.println(1);
}
}
class B{
static{
System.out.println(2);
}
public static void main(String args[]){
A o1=new A(); //클래스 A라는게 사용되기전에 클래스A 호출됨 (A사용안하면 호출안됨)
A o2=new A(); //즉 A객체 생성안하면 호출안됨!!!
A o3=new A();
}
}
//객체3번생성해도 클래스는 한번밖에 로딩안됨! 따라서 2 1 이 출력
//2 1
[ex]
static int a=100;
static{
int b=100;
System.out.println(a); //100
}
이렇게한다해도 메모리에 b는 올라가있지만 다른곳에서 클래스 이름으로 b를 부르거나 어떻게 부를수없음
왜냐하면 지역변수이기때문!!
# final
의미 : 마지막
위치 : 클래스앞(상속안됨), 메서드앞(오버라이딩금지), 변수앞(재할당금지지)(멤버,매개,지역변수모두..)
[ex]
final class A{
}
class B extends A{ // 컴파일에러. 상속안됨
}
[ex] 오버라이딩조건
1. 메서드의 선언부는 같아야한다.
2. private, final, static 선언되어 있다면 오버라이딩할 수 없다.
(오버라이딩할때 메서드앞에 static붙이면 오류는안남??)
class A{
final void m(){
}
}
class B extends A{
void m(){ // 컴파일에러, 오버라이딩안됨
}
}
[ex]
class A{
void m(final int a){
a=100; // 컴파일에러(재할당안됨)
}
}
class B{
void test(){
A o=new A();
o.m(0);
}
}
[ex]
class A{
void m(){
final int a=100;
a=200; // 컴파일에러(재할당안됨)
}
}
# 멤버변수앞의 final
[ex]
class A{
final int a;
A(){
a=100; // 생성자에서 값할당은 허용한다.(멤버변수앞에 final이 붙었을경우만!!)...
// 같은클래스에서만가능하고 다른클래스에선안됨...밑예제...
}
void m(){
a=200; // 컴파일에러...같은클래스내의 생성자에서만 가능하지 메서드에서는 안됨
}
}
[ex]
/*
package java.lang;
public class Math{
public static final double PI=3.14xxxxxxx;
// ststic이라서 다른클래스에서 그냥 접근은 가능하나 final이라서 변경은 불가능
}
*/
class A{
void m(){ //생성자로 바꿔주어도 ( A(){} ) 다른클래스라서 안됨
// 이런식으로 고유 값을 변경 불가능하게 함!
int r=10;
//Math.PI=3.15; 컴파일에러
System.out.println(2*Math.PI*r);
}
}
# abstract
의미 : 추상적(미완성)
위치 : 클래스앞(객체생성안됨), 메서드앞(메서드를 오버라이딩하게끔 강제하기 위해서...)
[ex]
abstract class A{
int a=100;
}
class B{
public static void main(String args[]){
A o=new A(); // 컴파일에러.... abstract라서 클래스 A는 주소생성(객체생성) 안됨!!!
System.out.println(o.a);
}
}
[ex] 추상메서드는 메서드의 body를 선언할 수 없다.
추상메서드를 가진 클래스는 자동으로 추상클래스라고 선언해야한다.
class A{ // 추상메서드를 가지고있는 클래스는 추상클래스로 선언해야함
// (반대는상관없음..추상클래스안에 일반메서드 O)
abstract void m(){ //오류 ... 추상메서드는 바디를 가질수없다.
}
}
//아래와같이해줘야 오류안남
// abstract class A{
// abstract void m();
// }
abstract class A{
abstract void m();
void m2(){
}
}
class B extends A{
void m(){ //자식클래스가 추상될필요가없고 단지 부모의추상메서드를 오버라이딩만하면됨
}
}
//핵심은 상속인데 부모가 추상메서드를 가지면 부모클래스도 추상클래스가되어야하는데 상속에의해
// 자식도 부모의 추상메서드를 가지게됨
// 따라서 자식클래스도 자동으로 추상클래스가되어야함... 하지만 이런건 좋지않음 그래서 abstract의
// 원래 목적은 자식도 추상클래스가 되는것이 아니고 부모의 메서드와 클래스가 추상이면
// 자식은 단지 부모의 추상메서드를 오버라이딩만하면됨 (자식클래스는 abstract일필요가없음)
// 즉, 부모의 추상메서드를 강제적으로 자식에서 오버라이딩하게끔하는 역활
[ex]
abstract class Animal{ //추상메서드를가진클래스라서 자동으로 추상클래스라고해야함
abstract void sound(); //자손에서 오버라이딩을꼭해야 에러안남...추상메서드는
//바디를 가질수없음(어차피 오버라이딩해야하기때문?)
}
class Dog extends Animal{
void sound(){
System.out.println("멍멍");
}
}
class Cat extends Animal{
void sound(){
System.out.println("야옹");
}
}
class SoundTest{
void test(Animal animal){ // Animal animal=new Animal();
// ==> Animal animal=new Dog(); animal은 다형적변수
animal.sound(); // 다형적 변수는 오버라이딩 된것을 호출함
} // 물론 (Animal animal) 대신 (Dog animal) 해도 오류는안남(Dog만불렀기때문에)
} // 하지만 메인메서드에서 Cat도 부른다면 (Dog cat) 이되기때문에 오류...
// 부모인 (Animal animal)
// 해줘야 Cat도 부를수있음 ...
class A{
public static void main(String args[]){
Dog dog=new Dog();
SoundTest st=new SoundTest();
st.test(dog); //dog=new Dog();
}
}
# 형변환
1 수치형간의 형변환
2 참조형간의 형변환
# 자바의 자료형
1 기본형(논리형,문자형char,정수형byte short int long,실수형float double)
2 참조형(클래스형,배열형,인터페이스형)
8bit = 1byte
# 수치형의 값의 범위
byte 8칸 < char,short 16칸 < int 32칸< long 64칸 < float 32칸 < double 64칸
[ex] 컴파일에러가 발생하는 이유는?
class A{
public static void main(String args[]){
float f=3.5;
}
}
[ex] 숫자D : double 상수값
숫자F : float 상수값
숫자L : long 상수값
0x숫자 : 16진수
0숫자 : 8진수
0b숫자 : 2진수 (jdk7)
class A{
public static void main(String args[]){
int a=0x36; //16진수
System.out.println(a); // 54 10진수로 결과값출력
int b=037; // 8진수
System.out.println(b); // 31
int c=0b101; // 2진수
System.out.println(c); // 5
}
}
[ex]
class A{
public static void main(String args[]){
int a=0x1011;
System.out.println(a);
int b=0xab;
System.out.println(b);
}
}
[ex]
class A{
public static void main(String args[]){
for(char a='A'; a<='Z'; a++){
System.out.println(a);
}
}
} // A~Z
[ex]
class A{
public static void main(String args[]){
byte a=10;
byte b=3;
System.out.println(a & b); // 2
System.out.println(a | b); // 11
System.out.println(a ^ b); // 9 //다르면 1 같으면 0
}
}
[ex]
class A{
public static void main(String args[]){
B o=null;
System.out.println( 3>0 || o.a<0 ); true // 처음꺼만 트루면 뒤에꺼확인할필요없이
// 트루....속도가빠름(뒤에꺼는사실 오류이지만
// 뒤에꺼는실행조차안했음)
//System.out.println( 3>0 | o.a<0 ); 실행하면NullPointerException이 발생한다.
// | 하나짜리는 둘다(양쪽다) 검사
}
}
class B{
int a=1;
}
'자바' 카테고리의 다른 글
[자바기초요약9] 내부클래스 (0) | 2019.03.03 |
---|---|
소스 (0) | 2019.03.03 |
[자바기초요약6] this(), super(), 다형적변수, instanceof연산자, 참조형간의 형변환 (0) | 2019.03.03 |
[자바기초요약5] 메서드오버라이딩, 오버로딩, @Override, 생성자 (0) | 2019.03.03 |
[자바기초요약4] 패키지 , 상속 (0) | 2019.03.03 |